2021SC@SDUSC
源代码下载地址:https://gitee.com/zeusees/HyperLPR
源码配置的详情见第一篇分析
本篇内容将继续根据小组分配的任务进行分析,内容如下:
一、bitwise_not(...)
对于所有在区间[0,5]内的图片执行以下操作:
if ptype>0 and ptype<5:
# pass
plate = cv2.bitwise_not(plate)
bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0,~0=1
二、findContoursAndDrawBoundingBox(...)
对图片执行函数:
image_rgb = fm.findContoursAndDrawBoundingBox(plate)
其源码为:
def findContoursAndDrawBoundingBox(image_rgb):
line_upper = [];
line_lower = [];
line_experiment = []
grouped_rects = []
gray_image = cv2.cvtColor(image_rgb,cv2.COLOR_BGR2GRAY)
for k in np.linspace(-50, 0, 15):
binary_niblack = cv2.adaptiveThreshold(gray_image,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,17,k)
imagex, contours, hierarchy = cv2.findContours(binary_niblack.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
bdbox = cv2.boundingRect(contour)
if (bdbox[3]/float(bdbox[2])>0.7 and bdbox[3]*bdbox[2]>100 and bdbox[3]*bdbox[2]<1200) or (bdbox[3]/float(bdbox[2])>3 and bdbox[3]*bdbox[2]<100):
# cv2.rectangle(rgb,(bdbox[0],bdbox[1]),(bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]),(255,0,0),1)
line_upper.append([bdbox[0],bdbox[1]])
line_lower.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]])
line_experiment.append([bdbox[0],bdbox[1]])
line_experiment.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]])
# grouped_rects.append(bdbox)
rgb = cv2.copyMakeBorder(image_rgb,30,30,0,0,cv2.BORDER_REPLICATE)
leftyA, rightyA = fitLine_ransac(np.array(line_lower),3)
rows,cols = rgb.shape[:2]
leftyB, rightyB = fitLine_ransac(np.array(line_upper),-3)
rows,cols = rgb.shape[:2]
pts_map1 = np.float32([[cols - 1, rightyA], [0, leftyA],[cols - 1, rightyB], [0, leftyB]])
pts_map2 = np.float32([[136,36],[0,36],[136,0],[0,0]])
mat = cv2.getPerspectiveTransform(pts_map1,pts_map2)
image = cv2.warpPerspective(rgb,mat,(136,36),flags=cv2.INTER_CUBIC)
image,M = deskew.fastDeskew(image)
return image
该函数是一种有使用条件的方法,前提是车牌的6个字符不能有完全的粘连。首先是确定上下边界,把extend好的检测到的车牌区域提取出来。
接着使用多个参数对这个区域进行多次自适应二值化。我们对opencv中adaptiveThreshold函数的k的参数从选择从-50变化到0。做15次二值化。
接着对每次二值化的图像进行连通域分析寻找满足字符长宽比的轮廓。
接着我们要对下面的点做直线拟合,在做直线拟合之前特别的,我们要特别的介绍一下随机抽样一致(RANSAC)算法。
在实际应用中获取到的数据,常常会包含有噪声数据,这些噪声数据会使对模型的构建造成干扰,我们称这样的噪声数据点为outliers,那些对于模型构建起积极作用的我们称它们为inliers,RANSAC做的一件事就是先随机的选取一些点,用这些点去获得一个模型(这个讲得有点玄,如果是在做直线拟合的话,这个所谓的模型其实就是斜率),然后用此模型去测试剩余的点,如果测试的数据点在误差允许的范围内,则将该数据点判为inlier,否则判为outlier。inliers的数目如果达到了某个设定的阈值,则说明此次选取的这些数据点集达到了可以接受的程度,否则继续前面的随机选取点集后所有的步骤,不断重复此过程,直到找到选取的这些数据点集达到了可以接受的程度为止,此时得到的模型便可认为是对数据点的最优模型构建。
由于在做连通域分析的时候,我们仅仅使用满足字符长宽比例的boundingbox作为判断条件,所以会带来一定的噪声。如下图又下角就存在着满足条件的错误点。所以RANSAC算法能帮助我们剔除这些噪声点。
我们使用RANSAC算法对上图中的点进行拟合。
这样就找到了上边界和下边界,下面我们只需要把这个区域crop出来就行了。
参考文章:HyperLPR车牌识别技术算法之车牌精定位
作者:JackYu庾
原文链接:https://blog.csdn.net/Relocy/article/details/78705566