我正在编码的工具中的第一个处理步骤之一是找到4个大黑方的外角的坐标。然后它们将用于进行单应变换,以便对图像进行去偏斜/不旋转(a.k.a透视变换),最终得到矩形图像。这是一个例子 - 旋转和嘈杂 - 输入(download link here):
为了保留大方块,我正在使用morphological transformations,如关闭/打开:
import cv2, numpy as np
img = cv2.imread('rotatednoisy-cropped.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((30, 30), np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imwrite('output.png', img)
输入文件(download link):
形态变换后的输出:
问题:输出方块不再是方形,因此方形左上角的坐标根本不准确!
我可以减小内核大小,但是它会保留更多不需要的小元素。
问题:如何更好地检测方块的角落?
注意:
由于morphological closing只是一种扩张+侵蚀,我找到了罪魁祸首:
import cv2, numpy as np
img = cv2.imread('rotatednoisy-cropped.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((30, 30), np.uint8)
img = cv2.dilate(img, kernel, iterations = 1)
在这一步之后,它仍然可以:
然后
img = cv2.erode(img, kernel, iterations = 1)
给出
它已经不行了!
答案 0 :(得分:4)
有关如何对图像进行校正的详细说明,请参阅this link。
import libraries
Flask code
Tkinter code
if __name__ == '__main__':
window.mainloop() #for tkinter This will run first
app.run() #for flask This will run when I close the Tkinter windows
答案 1 :(得分:2)
您可以尝试搜索并过滤掉您的特定轮廓(黑色矩形)并使用键对其进行排序。然后为每个轮廓(左,右,顶部,底部)选择极值点,您将获得点。请注意,此方法仅适用于此图片,如果图片在其他方向受到影响,则必须相应地更改代码。我不是专家,但我希望这有点帮助。
import numpy as np
import cv2
img = cv2.imread("rotate.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray,150,255,cv2.THRESH_BINARY)
im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
contours.sort(key=lambda c: np.min(c[:,:,1]))
j = 1
if len(contours) > 0:
for i in range(0, len(contours)):
size = cv2.contourArea(contours[i])
if 90 < size < 140:
if j == 1:
c1 = contours[i]
j += 1
elif j == 2:
c2 = contours[i]
j += 1
elif j == 3:
c3 = contours[i]
j += 1
elif j == 4:
c4 = contours[i]
break
Top = tuple(c1[c1[:, :, 1].argmin()][0])
Right = tuple(c2[c2[:, :, 0].argmax()][0])
Left = tuple(c3[c3[:, :, 0].argmin()][0])
Bottom = tuple(c4[c4[:, :, 1].argmax()][0])
cv2.circle(img, Top, 2, (0, 255, 0), -1)
cv2.circle(img, Right, 2, (0, 255, 0), -1)
cv2.circle(img, Left, 2, (0, 255, 0), -1)
cv2.circle(img, Bottom, 2, (0, 255, 0), -1)
cv2.imshow("Image", img)
cv2.waitKey(0)
结果:
答案 2 :(得分:0)
您可以在使用合适的阈值进行二值化后将方块提取为单个blob,并根据大小选择合适的方块。如果需要,您也可以先使用中值滤波器去噪。
然后一个紧密旋转的边界矩形将为您提供角落(您可以通过在凸形船体上运行旋转卡尺来获得它。)