我是opencv的新手,从简单的验证码中提取char开始学习它。
经过一些努力,我得到了findContours和一些清洁图像的方法,有时可以,但不经常使用。

例如:

  • 我有一个原始图像(已经缩放到大尺寸):
    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP
  • 转换为灰度并使用cv2.threshold clean:
    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP
  • 使用cv2.findContours获取边界框:

  • python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHPW仅覆盖一半,而不是b

    我的代码:
    from StringIO import StringIO
    import string
    
    from PIL import Image
    import requests
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    def get_ysdm_captcha():
        url = 'http://www.ysdm.net/common/CleintCaptcha'
        r = requests.get(url)
        img = Image.open(StringIO(r.content))
        return img
    
    def scale_image(img, ratio):
        return img.resize((int(img.width*ratio), int(img.height*ratio)))
    
    def draw_rect(im):
        im = np.array(im)
    
        if len(im.shape) == 3 and im.shape[2] == 3:
            imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        else:
            imgray = im
    
        #plt.imshow(Image.fromarray(imgray), 'gray')
        pilimg = Image.fromarray(imgray)
        ret,thresh = cv2.threshold(imgray,127,255,0)
    
        threimg = Image.fromarray(thresh)
    
        plt.figure(figsize=(4,3))
        plt.imshow(threimg, 'gray')
        plt.xticks([]), plt.yticks([])
    
        contours, hierarchy = cv2.findContours(np.array(thresh),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
        areas = []
    
        for c in contours:
            rect = cv2.boundingRect(c)
            area = cv2.contourArea(c)
            areas.append(area)
            x,y,w,h = rect
    
            if area > 2000 or area < 200 : continue
    
            cv2.rectangle(thresh,(x,y),(x+w,y+h),(0,255,0),1)
            plt.figure(figsize=(1,1))
            plt.imshow(threimg.crop((x,y,x+w,y+h)), 'gray')
            plt.xticks([]), plt.yticks([])
    
        plt.figure(figsize=(10,10))
    
        plt.figure()
        plt.imshow(Image.fromarray(thresh), 'gray')
        plt.xticks([]), plt.yticks([])
    
    
    image = get_ysdm_captcha()
    im = scale_image(image, 3)
    im = np.array(im)
    
    imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    imgray = cv2.GaussianBlur(imgray,(5,5),0)
    # im = cv2.medianBlur(imgray,9)
    # im = cv2.bilateralFilter(imgray,9,75,75)
    
    draw_rect(imgray)
    

    我尽力编写以上代码。
    我想象的解决方案是:
  • 发现有什么方法可以告诉cv2.findContours我需要某种尺寸的4边界框
  • 尝试了一些不同的参数(我从http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours尝试了所有操作,但仍然无法正常工作)

  • 现在我被困住了,不知道如何改善cv2.findContours ...

    最佳答案

    您可以使用形态学操作来修改图像并填补空白,例如erodedilate
    看这里:
    http://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html

    原版的:

    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP

    扩张:

    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP

    顺便说一句:我将在原始图像中执行HSV分离步骤,删除所有“白色/灰色/黑色”内容(低饱和度)。这将减少斑点的数量。在转换为灰度之前,请执行此操作。

    结果过滤如下:饱和度> 90
    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP

    最终结果:(之前添加了模糊步骤)

    python - opencv findContours错过了一些区域。[未获得所有正确的边界框]-LMLPHP

    另外,如果始终存在渐变,则可以检测到该渐变并滤除更多颜色。但是,如果您刚刚开始图像处理,那就有点多了;)

    08-25 01:32