OpenCV中已知最小外接矩形获取矩形的四个顶点
时间: 2023-08-16 07:10:11 浏览: 104
在OpenCV中,可以通过cv2.boxPoints()函数来获取最小外接矩形的四个顶点坐标。该函数需要传入最小外接矩形的中心点坐标、宽度和高度、旋转角度,然后返回四个顶点的坐标。示例代码如下:
```
import cv2
import numpy as np
# 创建一个矩形
rect = ((100, 100), (200, 100), -45)
# 获取最小外接矩形的四个顶点
box = cv2.boxPoints(rect)
box = np.int0(box)
# 绘制矩形和顶点
img = np.zeros((512, 512, 3), dtype=np.uint8)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
for pt in box:
cv2.circle(img, tuple(pt), 5, (0, 255, 0), -1)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
其中,rect是最小外接矩形的描述信息,包括中心点坐标、宽度和高度、旋转角度。boxPoints()函数返回的是浮点型坐标,需要使用np.int0()函数将其转换为整型坐标。最后,可以使用cv2.drawContours()函数绘制矩形和cv2.circle()函数绘制顶点。
相关问题
c++写一个函数OpenCV中已知最小外接矩形获取矩形的四个顶点,不使用cv::boxPoints(),添加注释为哪一个顶点
以下是C++代码实现,使用了cv::RotatedRect类和cv::Point2f类来计算最小外接矩形的四个顶点,并按照顺时针方向将它们存储到了一个std::vector<cv::Point2f>中。注释中标明了各个顶点的位置。
```
#include <opencv2/opencv.hpp>
#include <vector>
std::vector<cv::Point2f> getRectCorners(const cv::RotatedRect& rect)
{
std::vector<cv::Point2f> corners(4);
cv::Point2f center = rect.center;
// 旋转矩形的四个顶点
cv::Point2f vtx[4];
rect.points(vtx);
// 对顶点进行排序,按照顺时针方向存储到 corners 容器中
for (int i = 0; i < 4; i++)
{
cv::Point2f v = vtx[i];
if (v.x < center.x && v.y < center.y)
{
corners[1] = v; // 左上角
}
else if (v.x >= center.x && v.y < center.y)
{
corners[2] = v; // 右上角
}
else if (v.x >= center.x && v.y >= center.y)
{
corners[3] = v; // 右下角
}
else
{
corners[0] = v; // 左下角
}
}
return corners;
}
int main()
{
// 创建一个旋转矩形
cv::RotatedRect rect(cv::Point2f(100, 100), cv::Size2f(200, 100), -45);
// 获取最小外接矩形的四个顶点
std::vector<cv::Point2f> corners = getRectCorners(rect);
// 在图像中绘制矩形和顶点
cv::Mat img = cv::Mat::zeros(512, 512, CV_8UC3);
cv::Point2f p1 = corners[0];
cv::Point2f p2 = corners[1];
cv::Point2f p3 = corners[2];
cv::Point2f p4 = corners[3];
cv::line(img, p1, p2, cv::Scalar(0, 0, 255), 2);
cv::line(img, p2, p3, cv::Scalar(0, 0, 255), 2);
cv::line(img, p3, p4, cv::Scalar(0, 0, 255), 2);
cv::line(img, p4, p1, cv::Scalar(0, 0, 255), 2);
cv::circle(img, p1, 5, cv::Scalar(0, 255, 0), -1);
cv::circle(img, p2, 5, cv::Scalar(0, 255, 0), -1);
cv::circle(img, p3, 5, cv::Scalar(0, 255, 0), -1);
cv::circle(img, p4, 5, cv::Scalar(0, 255, 0), -1);
cv::imshow("image", img);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
```
在上面的代码中,getRectCorners()函数接收一个cv::RotatedRect类型的参数,表示最小外接矩形的信息。函数内部使用cv::RotatedRect::points()函数获取旋转矩形的四个顶点,并按照顺时针方向将它们存储到一个std::vector<cv::Point2f>中。在主函数中,使用cv::line()函数绘制矩形边框,使用cv::circle()函数绘制四个顶点。注释中标明了各个顶点的位置。
opencv根据最小外接矩形的四个顶点划分roi
可以使用 OpenCV 中的 `warpAffine()` 函数来根据最小外接矩形的四个顶点划分一个 ROI 区域。
具体步骤如下:
1. 根据最小外接矩形的四个顶点,计算出旋转矩阵和变换矩阵。
```python
import cv2
import numpy as np
# 假设四个点的坐标为 rect
rect = np.array([(x0, y0), (x1, y1), (x2, y2), (x3, y3)], dtype=np.float32)
# 计算最小外接矩形的中心点和大小
rect_center, rect_size, rect_angle = cv2.minAreaRect(rect)
# 计算旋转矩阵和变换矩阵
M = cv2.getRotationMatrix2D(rect_center, rect_angle, 1)
```
2. 将 ROI 区域的四个顶点坐标进行仿射变换,得到变换后的坐标。
```python
# 定义 ROI 区域的四个顶点坐标
roi_rect = np.array([(x0, y0), (x1, y1), (x2, y2), (x3, y3)], dtype=np.float32)
# 进行仿射变换
roi_rect_transformed = cv2.transform(np.array([roi_rect]), M)[0]
```
3. 根据变换后的坐标,计算出 ROI 区域的左上角坐标和大小。
```python
# 计算变换后的坐标的最大值和最小值
x_min, y_min = roi_rect_transformed.min(axis=0)
x_max, y_max = roi_rect_transformed.max(axis=0)
# 计算 ROI 区域的左上角坐标和大小
roi_x, roi_y = int(x_min), int(y_min)
roi_w, roi_h = int(x_max - x_min), int(y_max - y_min)
```
4. 利用 `warpAffine()` 函数进行 ROI 区域的截取。
```python
# 读取原图像
img = cv2.imread('your_image_path')
# 利用 warpAffine() 函数进行变换
roi_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
# 截取 ROI 区域
roi = roi_img[roi_y:roi_y+roi_h, roi_x:roi_x+roi_w]
```