做网站时怎样图片上传怎么才能让图片不变形有什么插件吗网站发展方向

当前位置: 首页 > news >正文

做网站时怎样图片上传怎么才能让图片不变形有什么插件吗,网站发展方向,安徽省住房和城乡建设厅网站领域,济南品牌网站建设价格低| 利用opencv实现车牌检测 整体流程涉及5个部分 图像通道转换对比度增强边缘连接二值化边界区域裁剪 图像通道转换 将RGB图像转换为HSV图像#xff0c;仅保留V通道。V通道表示颜色的明暗#xff0c;常用于图像对比度拉伸、直方图均衡化等流程。 原图像#xff1a; V通…| 利用opencv实现车牌检测 整体流程涉及5个部分 图像通道转换对比度增强边缘连接二值化边界区域裁剪 图像通道转换 将RGB图像转换为HSV图像仅保留V通道。V通道表示颜色的明暗常用于图像对比度拉伸、直方图均衡化等流程。 原图像 V通道图像
对比度增强 通过顶帽变换来实现对比度增强。顶帽变换用于提取图像的小区域和局部细节。白顶帽变换用于提取图像中比周围环境亮的小物体或细节黑顶帽变换用于提取图像中比周围环境暗的小物体或细节。 白顶帽变换 黑顶帽变化 通过白顶帽、黑顶帽的联合处理 I e n h a n c e d I o r i g i n a l I w h i t e − t o p _ h a t − I b l a c k − t o p _ h a t I{enhanced}I{original}I{white-top_hat}-I{black-top_hat} Ienhanced​Ioriginal​Iwhite−top_hat​−Iblack−tophat​其中 I o r i g i n a l I{original} Ioriginal​表示原图像 I w h i t e − t o p _ h a t I_{white-top_hat} Iwhite−top_hat​表示白顶帽处理后图像 I b l a c k − t o p _ h a t I_{black-top_hat} Iblack−top_hat​表示黑顶帽处理后图像得到对比度增强后的图像 边缘连接 增强对比度后很多车牌边缘不连续例如 需要通过膨胀操作Dilation Operation来扩展边缘实现边缘连接的目的。 添加膨胀操作后图像转变为
二值化 将单通道V图像转换为二值图像具体策略为Adaptive thresholding
边界区域裁剪 首先利用cv2.findContours检测边界并且获得边界的层级hierarchy。车牌检测可以理解为找到内边界而整个图像的背景可以理解为是外边界。下图是检测出的内边界 对内边界进行阈值判断处理过滤掉明显错误的情况。例如过滤面积小于2000的内边界具体数值需要按照实际情况来定对于每个内边界计算外接最小的矩形可以通过统计边界内最左、最上、最右、最下的点来合成矩形作为初步检测框 有一些检测框可能包括多个车牌宽度、高度比较大。对于这种情况需要对检测框按照宽度、高度均匀分割。以下是一个高度过大的例子需按高度均分 有一些车牌因为自身比较模糊导致检测框不准确可以通过统计信息来过滤掉本方法暂不处理。例如
最终整张图有41个车牌通过上述方法检测到了40个车牌效果不错。漏检的车牌本身边缘不清晰检测难度较大
消融实验 方法最终图像检测框车牌检测数量最终方法40去掉对比度增强39去掉边缘连接39内边界面积过滤阈值400038内边界面积过滤阈值500038 代码 主要的步骤为 1提取单通道图片选项为 灰度图片/HSV中的value分支 2提升对比度选项为 形态学中的顶帽/灰度拉伸 3边缘连接膨胀 4二值化 5利用findcontours函数找到边缘 6裁剪图片车牌图片存储

  1. 对车牌预处理 8方向矫正 9车牌精确区域搜索 10 字符分割 11 字符识别 import cv2 import copy import numpy as np import math import osdef SingleChannel(img) :用于车牌检测得到单通道图片主要测试两种方式灰度通道以及hsv中的v通道:param img: 输入图片:return:hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV)hue, saturation, value cv2.split(hsv)cv2.imshow(SingleChannel, value)return valuedef Contrast(img) :用于车牌检测利用tophat提高图片对比度,:param img: 输入图片:return:kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# applying topHat/blackHat operationstopHat cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)cv2.imshow(tophat, topHat)blackHat cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)cv2.imshow(blackhat, blackHat)add cv2.add(img, topHat)subtract cv2.subtract(add, blackHat)cv2.imshow(Constrast, subtract)return subtractdef threshold(img) :用于车牌检测采用cv2.adaptiveThreshold方法对图片二值化:param img: 输入图像:return:thresh cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 19, 9)cv2.imshow(thresh, thresh)return threshglobal crop_num crop_num 0def drawCoutrous(img_temp) :对输入图像查找内边缘设置阈值去除一些面积较小的内边缘:param img_temp: 输入图像经过预处理:return:threshline 2000imgCopy copy.deepcopy(img_temp)contours, hierarchy cv2.findContours(imgCopy, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)# print(len(contours), contours[0].shape)# print(hierarchy.shape)maxarea 0conid 0img_zero np.zeros(img.shape)# print(img_zero.shape is : ,img_zero.shape)num_contours 0contoursList []for i in range(len(contours)) :if hierarchy[0][i][3] 0 :temparea math.fabs(cv2.contourArea(contours[i]))# print(math.fabs(cv2.contourArea(contours[i])))if temparea maxarea :conid imaxarea tempareaif temparea threshline :num_contours 1if num_contours % 7 0 :cv2.drawContours(img_zero, contours, i, (0,0,255),1)if num_contours % 7 1 :cv2.drawContours(img_zero, contours, i, (255,0,0),1)if num_contours % 7 2 :cv2.drawContours(img_zero, contours, i, (0,255,0),1)if num_contours % 7 3 :cv2.drawContours(img_zero, contours, i, (0,255,255),1)if num_contours % 7 4 :cv2.drawContours(img_zero, contours, i, (255,0,255),1)if num_contours % 7 5 :cv2.drawContours(img_zero, contours, i, (255,255,0),1)if num_contours % 7 6:cv2.drawContours(img_zero, contours, i, (255, 255, 255), 1)# print(contours[i].shape)contoursList.append(contours[i])# print(maxarea: ,maxarea)# print(number of contours is , num_contours)# cv2.drawContours(img_zero, contours, conid, (0, 0, 255), 1)cv2.imshow(with contours,img_zero)return contoursListdef DrawRectangle(img, img_temp, ConList) :得到车牌边缘的的xy坐标最小最大值再原图上绘制bounding box得到裁剪后的车牌图像:param img: 原图:param img_temp: 二值图像:param ConList: 图像的边缘轮廓:return: nulllength len(ConList)rectanglePoint np.zeros((length, 4, 1, 2), dtype np.int32)img_zeros np.zeros(img_temp.shape)img_copy copy.deepcopy(img)img_copy_1 copy.deepcopy(img)# print(img_zeros, length; , img_zeros.shape, length)for i in range(length) :contours ConList[i]minx, maxx, miny, maxy 1e6, 0, 1e6, 0for index_num in range(contours.shape[0]) :if contours[index_num][0][0] minx :minx contours[index_num][0][0]if contours[index_num][0][0] maxx :maxx contours[index_num][0][0]if contours[index_num][0][1] miny :miny contours[index_num][0][1]if contours[index_num][0][1] maxy :maxy contours[index_num][0][1]# print(minx, maxx, miny, maxy)rectanglePoint[i][0][0][0], rectanglePoint[i][0][0][1] minx, minyrectanglePoint[i][1][0][0], rectanglePoint[i][1][0][1] minx, maxyrectanglePoint[i][2][0][0], rectanglePoint[i][2][0][1] maxx, maxyrectanglePoint[i][3][0][0], rectanglePoint[i][3][0][1] maxx, miny# rectanglePoint.dtype np.int32# print(rectanglePoint[i].shape)crop_save(minx, maxx, miny, maxy, img_copy_1)# print(dx: ,maxx-minx,dy: ,maxy-miny, area: , (maxx-minx)*(maxy-miny))cv2.polylines(img_copy, [rectanglePoint[i]], True, (0,0,255),2)cv2.imshow(img_zeros_haha, img_copy)def crop_save(minx, maxx, miny, maxy, img_original) :裁剪原图根据minxmaxxminymaxy:param minx: x坐标最小值:param maxx: x坐标最大值:param miny: y坐标最小值:param maxy: y坐标最大值:param img_original: 由于需要将绘制结果再原图中显示输入原图:return:global crop_numepsx 60epsy 30dx maxx - minxdy maxy - minyif dx dy :returnif dx 600 - epsx :dx1, dx2, dx3, dx4 minx, minx 1 * int(dx / 3), minx 2 * int(dx / 3), maxxsavepth ./crop40/cropimg str(crop_num) .jpg# cv2.imwrite(save_pth, img_original[dx1:dx2, miny:maxy,:])cv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[miny:maxy, dx2:dx3, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[miny:maxy, dx3:dx4, :])crop_num 1elif dx 400 - epsx :dx1, dx2, dx3 minx, minx 1 * int(dx / 2), maxxsavepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[miny:maxy, dx2:dx3, :])crop_num 1elif dy 240 - epsy :dy1, dy2, dy3, dy4 miny, miny 1 * int(dy / 3), miny 2 * int(dy / 3), maxysavepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[dy1: dy2, minx:maxx, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[dy2: dy3, minx:maxx, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[dy3: dy4, minx:maxx, :])crop_num 1elif dy 160 - epsy :dy1, dy2, dy3 miny, miny 1 * int(dy / 2), maxysavepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[dy1: dy2, minx:maxx, :])crop_num 1savepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[dy2: dy3, minx:maxx, :])crop_num 1elif dx 200 epsx :dx1, dx2 minx, maxxsavepth ./crop40/cropimg str(crop_num) .jpgcv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num 1else :passif name main :pth License_plates.jpgimg cv2.imread(pth)img cv2.resize(img, (292 * 4, 173 * 4))cv2.imshow(original,img)# 1提取单通道图片选项为 灰度图片/HSV中的value分支singlechannel_img SingleChannel(img)# 2提升对比度contrast_img Contrast(singlechannel_img)# contrast_img singlechannel_img# 3边缘连接膨胀kernel np.ones((2, 2), np.uint8)dilation_img cv2.dilate(contrast_img, kernel, iterations1)cv2.imshow(dilate, dilation_img)# dilation_img contrast_img# 4 二值化threshold_img threshold(dilation_img)# 5利用findcontours函数找到边缘contoursList drawCoutrous(threshold_img)# 6 裁剪图片车牌图片存储DrawRectangle(img, threshold_img, contoursList)cv2.waitKey()cv2.destroyAllWindows()