【问题标题】:Edge based binarization基于边缘的二值化
【发布时间】:2018-06-09 18:24:12
【问题描述】:

我正在尝试实现在研究论文"Automatic License Plate Recognition Using Deep Learning Technique" 中编写的基于边缘的二值化算法,但我在实现它时得到了全黑的最终图像并且找不到问题。

import cv2
import numpy as np

def edge_based_binarization(image):
    edge_image = cv2.Canny(image, 0, 255)
    binary_image = np.zeros(shape=image.shape)
    Hblocks = 10
    Vblocks = 5

    blockH = np.floor(image.shape[0] * 1.0 / Vblocks)
    blockH = np.array(blockH, dtype=np.uint8)
    blockW = np.floor(image.shape[1] * 1.0 / Hblocks)
    blockW = np.array(blockW, dtype=np.uint8)

    for r in range(Vblocks):
        for c in range(Hblocks):
            r0 = r * blockH + 1
            c0 = c * blockW + 1

            imgblock = image[r0 : r0 + blockH, c0 : c0 + blockW]
            edgeblock = edge_image[r0 : r0 + blockH, c0 : c0 + blockW]

            t = find_threshold(imgblock, edgeblock)
            if(np.all(imgblock < t)):
                 binary_image[r0 : r0 + blockH, c0 : c0 + blockW] = 1
            else:
                 binary_image[r0 : r0 + blockH, c0 : c0 + blockW] = 0

    binary_image = np.array(binary_image, dtype=np.uint8)
    return binary_image

def find_threshold(imgblock,edgeblock):
    t1 = [ ]
    for r in range(3,imgblock.shape[0] - 2):
        for c in range(3,imgblock.shape[1] - 2):
            if(edgeblock[r,c] == 255 and edgeblock[r,c-1] == 0 and edgeblock[r,c+1] == 0):
                m = min(imgblock[r,c-2], imgblock[r,c+2])
                if m < 128:
                    t2 = np.mean(imgblock[r,c-2 : c+2]) * 1.0
                    t1.append(t2)                    
            if(edgeblock[r,c] == 255 and edgeblock[r-1,c] == 0 and edgeblock[r+1,c] == 0):
                m = min(imgblock[r-2,c], imgblock[r+2,c])
                if m < 128:
                    t2 = np.mean(imgblock[r-2 : r+2,c]) * 1.0
                    t1.append(t2)

    if len(t1) == 0:
        t = 0
    else:
        t = np.mean(t1) - np.std(t1)

    return t

img = cv2.imread("test1.jpg")
cv2.imshow("Orig", img)
img = edge_based_binarization(img)

cv2.imshow("Edge", img)
cv2.waitKey(0)

论文中给出的代码 find threshold function edge based binarization function

【问题讨论】:

    标签: python numpy opencv image-processing deep-learning


    【解决方案1】:

    将给出的代码与论文中所述的进行比较后,我必须说论文中附加的实现是错误的。

    我没有寻找另一个证据,但是从论文中所说的,该算法通过估计 10x5 像素区域内边缘像素的局部阈值来对图像进行二值化,然后从这些相当小的图像中组装整个二值图像补丁。

    给定的实现将图像分成 10 个垂直块和 5 个水平块,从而产生更大的区域。

    Hblocks = 10
    Vblocks = 5
    
    blockH = np.floor(image.shape[0] * 1.0 / Vblocks)
    blockH = np.array(blockH, dtype=np.uint8)
    blockW = np.floor(image.shape[1] * 1.0 / Hblocks)
    blockW = np.array(blockW, dtype=np.uint8)
    

    由于该算法总体上是正确的,因此在估计阈值时实际上只需要对块大小进行小幅修正和对范围大小进行小幅调整。

    #!/usr/bin/env python
    
    import cv2
    import numpy as np
    from sys import argv
    from math import floor
    
    
    def edge_based_binarization(image):
        edge_image = cv2.Canny(image, 0, 255)
        cv2.imwrite("edge.png", edge_image)
        binary_image = np.zeros(shape=image.shape)
    
        # Fix block sizes
        blockWidth = 10
        blockHeight = 5
    
        verticalBlocks = floor(image.shape[0] / blockHeight)
        horizontalBlocks = floor(image.shape[1] / blockWidth)
    
        for r in range(verticalBlocks):
            for c in range(horizontalBlocks):
                # Fix 1 pixel border
                r0 = r * blockHeight
                c0 = c * blockWidth
    
                imgblock = image[r0: r0 + blockHeight, c0: c0 + blockWidth]
                edgeblock = edge_image[r0: r0 + blockHeight, c0: c0 + blockWidth]
    
                t = find_threshold(imgblock, edgeblock)
                if(np.all(imgblock > t)):
                    binary_image[r0: r0 + blockHeight, c0: c0 + blockWidth] = 0
                else:
                     binary_image[r0: r0 + blockHeight, c0: c0 + blockWidth] = 1
    
        return binary_image * 255.0
    
    
    def find_threshold(imgblock, edgeblock):
        t1 = []
        # Adjust range indices
        # Otherwise it would result in an empty range for the 5px height
        for r in range(2, imgblock.shape[0] - 2):
            for c in range(2, imgblock.shape[1] - 2):
                if(edgeblock[r, c] == 255 and edgeblock[r, c - 1] == 0 and edgeblock[r, c + 1] == 0):
                    m = min(imgblock[r, c - 2], imgblock[r, c + 2])
                    if m < 128:
                        t2 = np.mean(imgblock[r, c - 2: c + 2])
                        t1.append(t2)
                if(edgeblock[r, c] == 255 and edgeblock[r - 1, c] == 0 and edgeblock[r + 1, c] == 0):
                    m = min(imgblock[r - 2, c], imgblock[r + 2, c])
                    if m < 128:
                        t2 = np.mean(imgblock[r - 2: r + 2, c])
                        t1.append(t2)
    
        if len(t1) == 0:
            t = 0
        else:
            t = np.mean(t1) - np.std(t1)
    
        return t
    
    img = cv2.imread(argv[1])
    cv2.imshow("Orig", img)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    bin_img = edge_based_binarization(img)
    
    cv2.imshow("Edge", bin_img)
    cv2.waitKey(0)
    

    【讨论】:

    • 感谢您的回答。您的更正效果很好,但我认为论文中的算法实现与伪代码不同,因为二值化图像与论文中显示的或几乎可识别的图像不同。
    • 正如我所说,我没有搜索参考,而仅依赖于论文中提供的信息。二值化与我的测试图像效果很好,但我无法判断所描述的算法是否正确。无论如何,我很高兴能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    相关资源
    最近更新 更多