【问题标题】:Remove features from binarized image从二值化图像中删除特征
【发布时间】:2014-05-07 03:49:36
【问题描述】:

我写了一个小脚本,将黑板图片转换成可以打印和标记的形式。

我拍了一张这样的照片:

自动裁剪并二值化。这是脚本的输出:

我想从图像中删除最大的连接黑色区域。有没有简单的方法可以做到这一点?

本来想腐蚀图像来消除文字,然后从原始二值化图像中减去腐蚀图像,但我不禁想到有更合适的方法。

【问题讨论】:

    标签: python image-processing numpy computer-vision scikit-image


    【解决方案1】:

    当然,您可以使用 findContours 或 floodFill 获得连接的组件(特定大小),然后擦除它们留下一些污点。但是,如果你想把它做对,你会首先考虑为什么你有黑色区域。

    您没有使用自适应阈值(局部自适应),这使您的输出对阴影敏感。尽量不要通过运行以下代码来获得黑色区域:

    Mat img = imread("desk.jpg", 0);
    Mat img2, dst;
    pyrDown(img, img2);
    adaptiveThreshold(255-img2, dst, 255,  ADAPTIVE_THRESH_MEAN_C,
            THRESH_BINARY, 9, 10); imwrite("adaptiveT.png", dst);
    imshow("dst", dst);
    waitKey(-1);
    

    将来,您可能会阅读有关自适应阈值以及如何在本地对颜色进行采样的内容。我个人发现对与图像渐变正交的二进制颜色(即在它的两侧)进行采样很有用。这样,白色和黑色的样本大小相等,这很重要,因为通常有更多的背景颜色会影响估计。使用SWTMSER 可能会给你更多关于文本分割的想法。

    【讨论】:

    • 这是一个很好的回应。该解决方案简单高效。
    【解决方案2】:

    我试过这个:

    import numpy as np
    import cv2
    
    im = cv2.imread('image.png')
    
    gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    grayout = 255*np.ones((im.shape[0],im.shape[1],1), np.uint8)
    blur = cv2.GaussianBlur(gray,(5,5),1)
    thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)
    contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    wcnt = 0
    for item in contours:
        area =cv2.contourArea(item) 
        print wcnt,area
        [x,y,w,h] = cv2.boundingRect(item)
        if area>10 and area<200:
            roi = gray[y:y+h,x:x+w]
    
            cntd = 0
            for i in range(x,x+w):
                for j in range(y,y+h):
                    if gray[j,i]==0:
                        cntd = cntd + 1
            density = cntd/(float(h*w))
    
            if density<0.5:
                for i in range(x,x+w):
                    for j in range(y,y+h):
                        grayout[j,i] = gray[j,i];
            wcnt = wcnt + 1
    
    cv2.imwrite('result.png',grayout)
    

    你必须平衡两件事,去除黑点,但要平衡黑点,不要丢失黑板上的内容。我得到的输出是这样的:

    【讨论】:

      【解决方案3】:

      这是一个 Python numpy 实现(使用我自己的mahotas 包)的最佳答案方法(我认为几乎相同):

      import mahotas as mh
      import numpy as np
      

      带有标准缩写的进口 mahotas 和 numpy

      im = mh.imread('7Esco.jpg', as_grey=1)
      

      加载图像并转换为灰色

      im2 = im[::2,::2]
      im2 = mh.gaussian_filter(im2, 1.4)
      

      下采样和模糊(用于速度和噪声去除)。

      im2 = 255 - im2
      

      反转图像

      mean_filtered = mh.convolve(im2.astype(float), np.ones((9,9))/81.)
      

      均值过滤是通过卷积“手动”实现的。

      imc = im2 > mean_filtered - 4
      

      您可能需要在此处调整数字 4,但它对这张图片效果很好。

      mh.imsave('binarized.png', (imc*255).astype(np.uint8))
      

      转换为 8 位并保存为 PNG 格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多