Python 寻找矩形的角点
我试图得到这个矩形的角: 我试着使用cv2.0(矩形,2,3,0.04),但我想由于图像亮度的原因,左边缘没有显示出来。因此,我尝试在使用cornerHarris之前应用一个阈值,但生成的图像显示沿边缘的许多顶点,无法过滤角 我知道在使用cornerHarris之前需要对其进行过滤,但我不知道如何过滤。有人能帮我解决这个问题吗 另外,我已经尝试过使用模糊,但它也不起作用Python 寻找矩形的角点,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,我试图得到这个矩形的角: 我试着使用cv2.0(矩形,2,3,0.04),但我想由于图像亮度的原因,左边缘没有显示出来。因此,我尝试在使用cornerHarris之前应用一个阈值,但生成的图像显示沿边缘的许多顶点,无法过滤角 我知道在使用cornerHarris之前需要对其进行过滤,但我不知道如何过滤。有人能帮我解决这个问题吗 另外,我已经尝试过使用模糊,但它也不起作用 import cv2 import numpy as np import matplotlib.pyplot as plt
import cv2
import numpy as np
import matplotlib.pyplot as plt
rectangle = cv2.imread('rectangle.png', cv2.IMREAD_GRAYSCALE)
rectangle = np.where(rectangle > np.mean(rectangle), 255, 0).astype(np.uint8)
dst_rectangle = cv2.cornerHarris(rectangle, 2, 3, 0.04)
dst_rectangle = cv2.dilate(dst_rectangle, None)
mask = np.where(dst_rectangle > 0.01*np.max(dst_rectangle), 255, 0).astype(np.uint8)
points = np.nonzero(mask)
plt.imshow(dst_rectangle, cmap='gray')
plt.plot(points[1], points[0], 'or')
plt.show()
您可以尝试使用自适应。然后,如果您只需要角点,您可以使用cornerHarris,或者根据您接下来需要执行的操作,您也可以找到有用的,它返回一个边界框列表我将通过在自适应阈值化后获取轮廓旋转边界框的角点来不同地处理它。这是我用Python/OpenCV编写的代码 输入:
阈值图像: 提取的矩形区域: 图像上的旋转边界框: 旋转的边界框角点:
[[446 335]
[163 328]
[168 117]
[451 124]]
(444, 335)
(167, 330)
(170, 120)
(448, 125)
添加: 这是一个略短的代码版本,可以通过在阈值设置之前添加一些高斯模糊来实现
import cv2
import numpy as np
# read image
img = cv2.imread("rectangle.png")
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = 255-gray
# blur image
blur = cv2.GaussianBlur(gray, (3,3), 0)
# do adaptive threshold on gray image
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 75, 2)
thresh = 255-thresh
# apply morphology
kernel = np.ones((5,5), np.uint8)
rect = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
rect = cv2.morphologyEx(rect, cv2.MORPH_CLOSE, kernel)
# thin
kernel = np.ones((5,5), np.uint8)
rect = cv2.morphologyEx(rect, cv2.MORPH_ERODE, kernel)
# get largest contour
contours = cv2.findContours(rect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for c in contours:
area_thresh = 0
area = cv2.contourArea(c)
if area > area_thresh:
area = area_thresh
big_contour = c
# get rotated rectangle from contour
rot_rect = cv2.minAreaRect(big_contour)
box = cv2.boxPoints(rot_rect)
box = np.int0(box)
for p in box:
pt = (p[0],p[1])
print(pt)
# draw rotated rectangle on copy of img
rot_bbox = img.copy()
cv2.drawContours(rot_bbox,[box],0,(0,0,255),2)
# write img with red rotated bounding box to disk
cv2.imwrite("rectangle_thresh.png", thresh)
cv2.imwrite("rectangle_outline.png", rect)
cv2.imwrite("rectangle_bounds.png", rot_bbox)
# display it
cv2.imshow("IMAGE", img)
cv2.imshow("THRESHOLD", thresh)
cv2.imshow("RECT", rect)
cv2.imshow("BBOX", rot_bbox)
cv2.waitKey(0)
阈值图像: 提取的矩形区域: 图像上的旋转边界框: 旋转的边界框角点:
[[446 335]
[163 328]
[168 117]
[451 124]]
(444, 335)
(167, 330)
(170, 120)
(448, 125)
我能够找到4个点中的3个,第4个点可以很容易地找到,因为它是矩形的。以下是我的解决方案:
导入cv2
将numpy作为np导入
img=cv2.imread('6dUIr.png',1)
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
#平滑图像
内核=np.one((5,5),np.float32)/25
gray=cv2.filter2D(灰色,-1,内核)
#直方图均衡化
clahe=cv2.createCLAHE(clipLimit=1.45,tileGridSize=(4,4))
cl1=类别应用(灰色)
#找边
边缘=cv2.Canny(cl1,4100)
#找到角落
dst=cv2.0(边缘,2,3,0.04)
#标记拐角时,结果被放大,这并不重要
dst=cv2.扩张(dst,无)
#阈值为最佳值,它可能因图像而异。
img[dst>0.25*dst.max()]=[0,0255]
cv2.imshow(“边”,边)
cv2.imshow(“输出”,img)
#cv2.imshow(“直方图均衡”,img_输出)
cv2.等待键(0)
这里有一个简单的方法:
- 获取二值图像。我们加载图像,灰度,高斯模糊,然后自适应阈值
- 形态学操作。我们创建一个矩形内核,并对其进行变形打开以去除小噪声
- 找到扭曲的矩形轮廓并绘制到遮罩上。找到轮廓,确定旋转的边界框,然后绘制到空白遮罩上
- 查找角点。我们使用已经实现的Shi-Tomasi角点检测器,与Harris角点检测器相比,它显示了更好的结果
以下是每个步骤的可视化: 二值图像 变形开放 找到旋转的矩形轮廓并在空白遮罩上绘制/填充 绘制旋转的矩形和角点以获得结果 角坐标
(448.0, 337.0)
(164.0, 332.0)
(452.0, 123.0)
(168.0, 118.0)
代码
我以前尝试过自适应阈值,但它会返回非常嘈杂的图像,更难过滤角点。我尝试只获取角点,以获得基于另一个图像的仿射变换矩阵,这更容易获得其角点。您可以尝试使用闭包运算符或查看此处。如果明天我有机会设置一个测试环境,我会更深入地了解,你能分享一个吗?我不确定这是否适合堆栈溢出。见:,。我认为描述我所做的就足够了。下次我将分享一个可复制的代码。谢谢你的建议。为什么只下一次?你仍然可以,而且应该,编辑你的帖子,不,完成了。因为问题已经解决了,三分对我来说已经足够了。我只需要图像的透视图就可以对另一幅图像进行仿射变换。谢谢你的帮助!请参阅我的答案中添加的代码,该代码的版本稍微高效一些。