gpt4 book ai didi

python - opencv2 Canny + findContours在某些图像上不起作用

转载 作者:行者123 更新时间:2023-12-02 17:31:59 25 4
gpt4 key购买 nike

我正在尝试创建一个程序,该程序将检测并去除图片中的边框,目标是检测图片中的文档并将其清理...

这是我的代码:

import sys
import cv2
import numpy as np
import rect

image = cv2.imread('./test.jpg')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 9)
ret, gray = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

edges = cv2.Canny(gray, 10, 250)
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)

#x,y,w,h = cv2.boundingRect(contours[0])
#cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),0)

# get approximate contour
for c in contours:
p = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * p, True)

if len(approx) == 4:
target = approx
break


cv2.drawContours(image, [target], -1, (0, 255, 0), 2)
cv2.imwrite('./final.jpg', image)

图像teste.jpg是:
enter image description here

但是现在...它唯一能找到的是:

enter image description here

...并根据要求提供一张有效的图片:

enter image description here

最佳答案

正如聊天中所讨论的,我建议您为此使用Feature Description and Matching。以我的经验,它比轮廓更快,并且您应该能够解决照明,视角等方面的变化问题。

这是我尝试过的:

import cv2
import numpy as np


def locater(image, source, num=0):
def resize(im, new_width):
r = float(new_width) / im.shape[1]
dim = (new_width, int(im.shape[0] * r))
return cv2.resize(im, dim, interpolation=cv2.INTER_AREA)
#width = 300
#source = resize(source, new_width=width)
#image = resize(image, new_width=width)

hsv = cv2.cvtColor(image, cv2.COLOR_BGR2LUV)
image, u, v = cv2.split(hsv)

hsv = cv2.cvtColor(source, cv2.COLOR_BGR2LUV)
source, u, v = cv2.split(hsv)

MIN_MATCH_COUNT = 10
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(image, None)
kp2, des2 = orb.detectAndCompute(source, None)

flann = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_FLANNBASED)

des1 = np.asarray(des1, dtype=np.float32)
des2 = np.asarray(des2, dtype=np.float32)

matches = flann.knnMatch(des1, des2, k=2)

# store all the good matches as per Lowe's ratio test
good = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
good.append(m)

if len(good) >= MIN_MATCH_COUNT:
src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()

h,w = image.shape
pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
source_bgr = cv2.cvtColor(source, cv2.COLOR_GRAY2BGR)
img2 = cv2.polylines(source_bgr, [np.int32(dst)], True, (0,0,255), 3,
cv2.LINE_AA)
cv2.imwrite("out"+str(num)+".jpg", img2)
else:
print("Not enough matches." + str(len(good)))
matchesMask = None

draw_params = dict(matchColor=(0, 255, 0), # draw matches in green color
singlePointColor=None,
matchesMask=matchesMask, # draw only inliers
flags=2)
img3 = cv2.drawMatches(image, kp1, source, kp2, good, None, **draw_params)
cv2.imwrite("ORB"+str(num)+".jpg", img3)

image = cv2.imread('contour.jpg')
source = cv2.imread('contour_source.jpg')
locater(source, image, num=1)

源图像:

Source

结果:

Result 1

Result 2

一些注意事项:由于源图像不太好,所以单应性很好。通过获得更好的图像质量,可以使图像更加准确-通过使用体面的扫描仪扫描原稿,调整图像大小(为此我添加了一个功能)以及使用不同的色彩空间(在这里使用LUV)。

希望能帮助到你!

关于python - opencv2 Canny + findContours在某些图像上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55014412/

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