我是openCV和计算机视觉的新手。刚才我正在尝试在检测到角点后裁剪Tiff扫描,然后使用python、openCV、numpy和OCR以及Tesseract根据精确的坐标x:y从中提取信息
我现在实现的是上传一个图像(扫描),对其进行二值化,修复旋转并删除空白。结果已经很好了,但还不够好。我的图像仍然总是有点旋转。下面是图像示例ExampleExample(w/o Arrows)
问题是:如何检测这些角点并裁剪它们之外的所有东西
这是我目前的代码:
for filenumber in range(2,7):
img = cv2.imread('img' + str(filenumber) + '.tif')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.bitwise_not(gray)
img = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 11)
kernel = np.ones((2, 2), np.uint8)
img = cv2.erode(img, kernel, iterations=3)
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
coords = np.column_stack(np.where(thresh > 0))
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
angle = -(90 + angle)
else:
angle = -angle
# rotate the image to deskew it
(h, w) = img.shape[:500]
center = (w // 400, h // 400)
M = cv2.getRotationMatrix2D(center, angle, 1)
rotated = cv2.warpAffine(img, M, (w, h),
flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
# draw the correction angle on the image so we can validate it
cv2.putText(rotated, "Angle: {:.2f} degrees".format(angle),
(100, 400), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)
img = rotated
th, threshed = cv2.threshold(img, 240, 255, cv2.THRESH_BINARY_INV)
## (2) Morph-op to remove noise
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)
## (3) Find the max-area contour
cnts = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
cnt = sorted(cnts, key=cv2.contourArea)[-1]
## (4) Crop and save it
x,y,w,h = cv2.boundingRect(cnt)
dst = img2[y:y+h, x:x+w]
img = dst
size_multiplier = szm = 1
cv2.imwrite('img_' + str(filenumber) + '_Cropped' + '.jpg', img)
#Configs for OCR segments
for nnumb in range(2, 7):
print('[INFO2]: File=' + str(filenumber) + '; nnumb=' + str(nnumb))
if nnumb == 1:
sub_image = img[130:130 + 90, 1220:1220 + 600]
config = ('-l rus --oem 0 --psm 3 -c tessedit_char_whitelist="0123456789"')
if nnumb == 2:
sub_image = img[150:150 + 60, 1980:1980 + 460]
config = ('-l rus --oem 1 --psm 3 -c tessedit_char_whitelist="0123456789"')
if nnumb == 3:
sub_image = img[230:230 + 70, 620:620 + 3000]
config = ('-l rus --oem 0 --psm 3')
if nnumb == 4:
sub_image = img[410:410 + 70, 835:835 + 470]
config = ('-l rus --oem 0 --psm 1 -c tessedit_char_whitelist="0123456789"')
if nnumb == 5:
sub_image = img[480:480 + 220, 610:610 + 1300]
config = ('-l rus --oem 0 --psm 3')
if nnumb == 6:
sub_image = img[720:720 + 70, 110:110 + 500]
config = ('-l rus --oem 0 --psm 3 -c tessedit_char_whitelist="0123456789"')
[
更新:最终代码
def cornersandcrop(img):
main_image = img
main_imageF = main_image.copy()
gray_image = main_image.copy()
#Remove parts of image except corners
gray_image[70:70 + 500, 70:70 + 500] = [255, 255, 255]
gray_image[44:44 + 100, 1900:1900 + 550] = [255, 255, 255]
gray_image[2270:2270 + 700, 45:45 + 200] = [255, 255, 255]
gray_image[140:2880, 0:2500] = [255, 255, 255]
gray_image[0:3000, 150:2350] = [255, 255, 255]
gray_image = cv2.cvtColor(gray_image, cv2.COLOR_BGR2GRAY)
gray_image = cv2.medianBlur(gray_image, 5)
gray_image = cv2.adaptiveThreshold(gray_image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,20)
kernel = np.ones((2, 2), np.uint8)
gray_image = cv2.erode(gray_image, kernel, iterations=5)
gray_image = cv2.dilate(gray_image, kernel, iterations=2)
gray_image = cv2.morphologyEx(gray_image, cv2.MORPH_OPEN, np.ones((1, 1), np.uint8))
template = cv2.imread('Templates\\Template_Corner_Top_Left.png', 0)
template2 = cv2.imread('Templates\\Template_Corner_Top_Right.png', 0)
template3 = cv2.imread('Templates\\Template_Corner_Bot_Right.png', 0)
template4 = cv2.imread('Templates\\Template_Corner_Bot_Left.png', 0)
width, height = template.shape[::-1] #get the width and height
width2, height2 = template2.shape[::-1]
width3, height3 = template3.shape[::-1]
width4, height4 = template4.shape[::-1]
match = cv2.matchTemplate(gray_image, template, cv2.TM_CCOEFF_NORMED)
match2 = cv2.matchTemplate(gray_image, template2, cv2.TM_CCOEFF_NORMED)
match3 = cv2.matchTemplate(gray_image, template3, cv2.TM_CCOEFF_NORMED)
match4 = cv2.matchTemplate(gray_image, template4, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match)
top_Pos1 = max_loc
Pos1 = (top_Pos1[0] + width-115, top_Pos1[1] + height-115)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match2)
top_Pos2 = max_loc
Pos2 = (top_Pos2[0] + width2-5, top_Pos2[1] + height2-115)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match3)
top_Pos3 = max_loc
Pos3 = (top_Pos3[0] + width3-5, top_Pos3[1] + height3-5)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match4)
top_Pos4 = max_loc
Pos4 = (top_Pos4[0] + width4-115, top_Pos4[1] + height4-5)
src_pts = np.array([Pos1, Pos2, Pos3, Pos4], dtype=np.float32)
dst_pts = np.array([[0, 0], [3000, 0], [3000, 2500], [0, 2500]], dtype=np.float32)
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warp = cv2.warpPerspective(main_imageF, M, (3000, 2500))
warp = cv2.resize(warp, (int(2500), int(3000)),fx=1, fy=1, interpolation = cv2.INTER_CUBIC)
return (warp)
这对我在Python/OpenCV中使用模板匹配定位一个角非常有用。只需使模板图像大于您的角落,使其周围有一些白色
输入:
模板:
资料:
结果:
您还可以优化结果以获得亚像素精度。见https://www.bbsmax.com/A/lk5aBbGod1/
将模板旋转3次,每次旋转90度,以形成其他3个模板,测量或计算从左上角到角线交点的偏移,并进行模板匹配。一旦你有了所有的4个匹配项,你就可以使用numpy切片进行裁剪了
我建议通过“调整过滤器”使用模板匹配:
0
替换为-1
,将255
替换为1
李>h
(用于查找左下角):-1
放在im
中的值需要为-1
的地方,将1
放在值需要为1
的地方李>h
中L形的角位于中心(这有点浪费-您可以避免它,稍后再固定位置)李>0 -1 1 0 0
0 -1 1 0 0
0 -1 1 1 1
0 -1 -1 -1 -1
0 0 0 0 0
h
筛选im
-输出的最大值是最匹配h
的位置李>下面是找到左下角的代码示例:
结果(左下角):
筛选内核(作为映像):
更新:
如果还有其他“L形”对象,您可能需要使用更“激进”的内核
例如:
相关问题 更多 >
编程相关推荐