gpt4 book ai didi

python - 使用 Opencv 检测图像中矩形的中心和角度

转载 作者:太空狗 更新时间:2023-10-29 18:21:01 26 4
gpt4 key购买 nike

我有一张图片如下:

Sample image containing many rectangle contours

我需要找出矩形的数量、每个矩形的中心以及平行于通过中心的矩形长边的轴之间的角度,并从水平方向测量逆时针方向的角度。我发现了图像中矩形的数量。我对找出反射的中心和角度感到震惊。通过瞬间找到中心并没有给我正确的答案。

我的代码:

import cv2
import numpy as np
import sys

img = cv2.imread(str(sys.argv[1]),0)
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh,1,2)



for contour in contours:
area = cv2.contourArea(contour)
if area>100000:
contours.remove(contour)




cnt = contours[0]

epsilon = 0.02*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

print 'No of rectangles',len(approx)


#finding the centre of the contour
M = cv2.moments(cnt)

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

print cx,cy

最佳答案

这就是使用 openCV 的 minAreaRect 函数可以做到的。它是用 C++ 编写的,但您可能可以轻松适应它,因为几乎只使用了 OpenCV 函数。

    cv::Mat input = cv::imread("../inputData/rectangles.png");

cv::Mat gray;
cv::cvtColor(input,gray,CV_BGR2GRAY);

// since your image has compression artifacts, we have to threshold the image
int threshold = 200;
cv::Mat mask = gray > threshold;

cv::imshow("mask", mask);

// extract contours
std::vector<std::vector<cv::Point> > contours;
cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

for(int i=0; i<contours.size(); ++i)
{
// fit bounding rectangle around contour
cv::RotatedRect rotatedRect = cv::minAreaRect(contours[i]);

// read points and angle
cv::Point2f rect_points[4];
rotatedRect.points( rect_points );

float angle = rotatedRect.angle; // angle

// read center of rotated rect
cv::Point2f center = rotatedRect.center; // center

// draw rotated rect
for(unsigned int j=0; j<4; ++j)
cv::line(input, rect_points[j], rect_points[(j+1)%4], cv::Scalar(0,255,0));

// draw center and print text
std::stringstream ss; ss << angle; // convert float to string
cv::circle(input, center, 5, cv::Scalar(0,255,0)); // draw center
cv::putText(input, ss.str(), center + cv::Point2f(-25,25), cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(255,0,255)); // print angle
}

生成这张图片:

enter image description here

如您所见,角度可能不是您想要的(因为它们随机使用较长或较小的线作为引用)。您可以改为提取矩形的较长边并手动计算角度。

如果您选择旋转矩形的较长边并从中计算角度,它看起来像这样:

// choose the longer edge of the rotated rect to compute the angle
cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);

cv::Point2f usedEdge = edge1;
if(cv::norm(edge2) > cv::norm(edge1))
usedEdge = edge2;

cv::Point2f reference = cv::Vec2f(1,0); // horizontal edge


angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));

给出这个结果,这应该就是你要找的!

enter image description here

编辑:运算符(operator)似乎没有使用他发布的输入图像,因为引用矩形中心位于图像之外。

使用这个输入(手动重新缩放但可能仍然不是最佳的):

enter image description here

我得到了这些结果(蓝点是操作提供的引用矩形中心):

enter image description here

将引用与检测进行比较:

reference (x,y,angle)    detection (x,y,angle)
(320,240,0) (320, 240, 180) // angle 180 is equal to angle 0 for lines
(75,175,90) (73.5, 174.5, 90)
(279,401,170) (279.002, 401.824, 169.992)
(507,379,61) (507.842, 379.75, 61.1443)
(545,95,135) (545.75, 94.25, 135)
(307,79,37) (306.756, 77.8384, 37.1042)

虽然我很想看到真实的输入图像,也许结果会更好。

关于python - 使用 Opencv 检测图像中矩形的中心和角度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34237253/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com