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