使用opencv2区分图像中的矩形和正方形python
Differentiation between rectangle and square in image using opencv2 python
我正在学习如何识别所提供图像中的形状。我能够通过几何体存在的边数来识别形状。但是现在我想知道有什么方法可以区分图像中的正方形和矩形吗?
这是我的代码。目前我只是在绘制几何图形的轮廓。
import cv2
raw_image = cv2.imread('test1.png')
cv2.imshow('Original Image', raw_image)
cv2.waitKey(0)
bilateral_filtered_image = cv2.bilateralFilter(raw_image, 5, 175, 175)
cv2.imshow('Bilateral', bilateral_filtered_image)
cv2.waitKey(0)
edge_detected_image = cv2.Canny(bilateral_filtered_image, 75, 200)
cv2.imshow('Edge', edge_detected_image)
cv2.waitKey(0)
_, contours, hierarchy = cv2.findContours(edge_detected_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_list = []
for contour in contours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
area = cv2.contourArea(contour)
if ((len(approx) >= 3)):
contour_list.append(contour)
cv2.drawContours(raw_image, contour_list, -1, (0,0,0), 2)
cv2.imshow('Objects Detected',raw_image)
cv2.waitKey(0)
我有另一种方法:
求出所有的连通分量。
在原始图像中找到特征点,因为在这种情况下我们有简单的几何体而不是复杂的物体,你可以使用Harris角点算法将角点作为特征点。
将位于相同连通分量上的这些特征点分组。
利用所有连通分量上这些特征点之间的关系(distance/angle),据此可以对这些几何形状进行分类。
如果宽度和高度相同,则为正方形。否则它是一个矩形。
for contour in contours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
area = cv2.contourArea(contour)
if ((len(approx) == 4)):
(x, y, w, h) = cv2.boundingRect(approx)
if ((float(w)/h)==1):
cv2.putText(raw_image, "square", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)
else:
cv2.putText(raw_image, "rectangle", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)
contour_list.append(contour)
此更改仅检测正方形和矩形。在 for 循环中进行必要的更改以检测圆圈。您可以使用 len(approx)
来区分。
长方形和正方形的区别在于,正方形有4条相等的边,是一种特殊的长方形。这是我在幼儿园学的。
有无数种方法可以识别正方形。
它的周长总是等于 sqrt(面积) 因此它的圆度总是 0.0625
所有角之间的距离是a或a
*开方(2)
质心到所有 4 条边的距离都为 a / 2
...
你说了算。
我在评论中看到形状可能会旋转。在那种情况下 cv2.boundingRect() 将不会给出正确的结果,因为该函数总是给出一个直立的矩形。为了检测一般的矩形(旋转或不旋转),您应该尝试 cv2.minAreaRect() ,它将 return 一个矩形,该矩形将根据轮廓旋转并且具有覆盖轮廓的最小面积。然后你可以检查它的宽高比,看看它是正方形还是长方形。
我正在学习如何识别所提供图像中的形状。我能够通过几何体存在的边数来识别形状。但是现在我想知道有什么方法可以区分图像中的正方形和矩形吗? 这是我的代码。目前我只是在绘制几何图形的轮廓。
import cv2
raw_image = cv2.imread('test1.png')
cv2.imshow('Original Image', raw_image)
cv2.waitKey(0)
bilateral_filtered_image = cv2.bilateralFilter(raw_image, 5, 175, 175)
cv2.imshow('Bilateral', bilateral_filtered_image)
cv2.waitKey(0)
edge_detected_image = cv2.Canny(bilateral_filtered_image, 75, 200)
cv2.imshow('Edge', edge_detected_image)
cv2.waitKey(0)
_, contours, hierarchy = cv2.findContours(edge_detected_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_list = []
for contour in contours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
area = cv2.contourArea(contour)
if ((len(approx) >= 3)):
contour_list.append(contour)
cv2.drawContours(raw_image, contour_list, -1, (0,0,0), 2)
cv2.imshow('Objects Detected',raw_image)
cv2.waitKey(0)
我有另一种方法:
求出所有的连通分量。
在原始图像中找到特征点,因为在这种情况下我们有简单的几何体而不是复杂的物体,你可以使用Harris角点算法将角点作为特征点。
将位于相同连通分量上的这些特征点分组。
利用所有连通分量上这些特征点之间的关系(distance/angle),据此可以对这些几何形状进行分类。
如果宽度和高度相同,则为正方形。否则它是一个矩形。
for contour in contours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
area = cv2.contourArea(contour)
if ((len(approx) == 4)):
(x, y, w, h) = cv2.boundingRect(approx)
if ((float(w)/h)==1):
cv2.putText(raw_image, "square", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)
else:
cv2.putText(raw_image, "rectangle", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)
contour_list.append(contour)
此更改仅检测正方形和矩形。在 for 循环中进行必要的更改以检测圆圈。您可以使用 len(approx)
来区分。
长方形和正方形的区别在于,正方形有4条相等的边,是一种特殊的长方形。这是我在幼儿园学的。
有无数种方法可以识别正方形。
它的周长总是等于 sqrt(面积) 因此它的圆度总是 0.0625
所有角之间的距离是a或a *开方(2)
质心到所有 4 条边的距离都为 a / 2
...
你说了算。
我在评论中看到形状可能会旋转。在那种情况下 cv2.boundingRect() 将不会给出正确的结果,因为该函数总是给出一个直立的矩形。为了检测一般的矩形(旋转或不旋转),您应该尝试 cv2.minAreaRect() ,它将 return 一个矩形,该矩形将根据轮廓旋转并且具有覆盖轮廓的最小面积。然后你可以检查它的宽高比,看看它是正方形还是长方形。