基于边缘的二值化

时间:2017-12-29 09:39:57

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

我正在尝试实现研究论文"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

1 个答案:

答案 0 :(得分:0)

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

我没有搜索另一个证据,但是根据论文中的说法,该算法通过估算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)