基于边缘的二值化

问题描述 投票:1回答:1

我正在尝试实现在研究论文"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个回答
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)
© www.soinside.com 2019 - 2024. All rights reserved.