检测具有相似颜色背景的图像的边缘。

最后发布: 2020-07-09


问题

我正在尝试使用openCV和python来提取图像的细节,然后将其存储在csv中,由于从文本中检索数据将提高OCR的准确性,我正在尝试对图像进行预处理,并生成一个鸟瞰图,图像有很多噪音,背景与感兴趣区域的颜色相似。

图片来源

enter image description here

办法1) 我使用高斯模糊,然后用自适应阈值来去除一些噪声.接着用形态学变换得到一个公平的二进制图像.然后我用外部层次结构搜索这个区域的轮廓,然后根据区域进行排序.另外,在卡片边缘产生的轮廓是开放的,因此按区域排序并不像我预期的那样工作.但我无法得出所需的输出.

def pre_process_image(img, skip_dilate=False):

  proc = cv2.GaussianBlur(img.copy(), (9, 9), 0)
  # ret, proc = cv2.threshold(proc,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  # edged = cv2.Canny(proc, 100, 200)
  proc = cv2.adaptiveThreshold(proc, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

  if not skip_dilate:
    kernel = np.array([[0., 1., 1.], [1., 1., 1.], [1., 1., 0.]], np.uint8)
    proc = cv2.dilate(proc, kernel)
  # proc = cv2.erode(proc.copy(), cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)), iterations = 1)  
  return proc

processed = pre_process_image(res.copy())
contours = cv2.findContours(processed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # Find contours
contours = imutils.grab_contours(contours)
contours = sorted(contours, key = cv2.contourArea, reverse = True)

max_len = 0
for cnt in contours:
  if(cv2.arcLength(cnt, False) > max_len):
    max_len = cv2.arcLength(cnt, False)
    connt = cnt


p = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
external_only = cv2.drawContours(p.copy(), connt, -1, (255, 0, 0), 2)

LOL epic Fail

方法2) HoughTransform在基本的预处理后检测边缘。

blur = cv2.GaussianBlur(img, (9, 9), 0) 

# res = cv2.equalizeHist(blur)
# res2 = np.hstack((gray, tut))

# # Apply edge detection method on the image 
edges = cv2.Canny(blur,50,150,apertureSize = 3) 

lines = cv2.HoughLines(edges,1,np.pi/180, 50) 

for r,theta in lines[0]: 

   a = np.cos(theta) 
   b = np.sin(theta) 

   x0 = a*r 
   y0 = b*r 
   x1 = int(x0 + 1000*(-b)) 
   y1 = int(y0 + 1000*(a)) 
   x2 = int(x0 - 1000*(-b)) 
   y2 = int(y0 - 1000*(a)) 

   cv2.line(img,(x1,y1), (x2,y2), (0,0,255),4)

lol fail

如果有人能指出我的错误,并sujjest一个更有效的方法来实现良好的结果,那将是非常有帮助的.我是一个初学者的图像处理,所以可能不知道大多数的理论,但一个好的diretion向前工作将是非常感激的.TIA!

python-3.x opencv image-processing computer-vision
回答

可以使用预处理图像(删除颜色元素)。

import cv2 as cv
low_H = 0
low_S = 50
low_V = 0
high_H = 255
high_S = 255
high_V = 255
frame = cv.imread('IE.jpg')
frame_HSV = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
frame_threshold = cv.inRange(frame_HSV, (low_H, low_S, low_V), (high_H, high_S, high_V))
blank=cv.cvtColor(frame_threshold, cv.COLOR_GRAY2BGR) 
out=cv.bitwise_or(frame, blank)
out=cv.cvtColor(out, cv.COLOR_BGR2GRAY)
cv.imwrite('out_card.png', out)

enter image description here