代码解释:public static String charsSegment(Mat inMat, PlateColor color, Boolean debug, String tempPath) { int charCount = 7; // 车牌字符个数 if (color.equals(PlateColor.GREEN)) { charCount = 8; } // 切换到灰度图 Mat gray = new Mat(); Imgproc.cvtColor(inMat, gray, Imgproc.COLOR_BGR2GRAY); ImageUtil.gaussianBlur(gray, gray, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_CHAR_PLATE_PREDICT, gray); // 图像进行二值化 Mat threshold = new Mat(); switch (color) { case BLUE: Imgproc.threshold(gray, threshold, 10, 255, Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY); break; default: // GREEN YELLOW Imgproc.threshold(gray, threshold, 10, 255, Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY_INV); break; } ImageUtil.debugImg(debug, tempPath, "plateThreshold", threshold); // 输出二值图 Imgcodecs.imwrite(tempPath + Constant.TEMP_CHAR_PLATE_PREDICT, threshold); // 边缘腐蚀 threshold = ImageUtil.erode(threshold, debug, tempPath, 2, 2); Imgcodecs.imwrite(tempPath + Constant.TEMP_CHAR_ERODE, threshold); // 垂直方向投影,错切校正 // 理论上,还可以用于分割字符 Integer px = getShearPx(threshold); ImageUtil.shearCorrection(threshold, threshold, px, debug, tempPath); // 前面已经结果错切校正了,可以按照垂直、水平方向投影进行精确定位 // 垂直投影 + 垂直分割线,分割字符 // 水平投影,去掉上下边框、铆钉干扰 threshold = sepAndClear(threshold, px, charCount, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_CHAR_SEP_AND_CLEAR, threshold); // 边缘膨胀 // 还原腐蚀操作产生的影响 // 会影响中文字符的精确度 threshold = ImageUtil.dilate(threshold, debug, tempPath, 2, 2, true); Imgcodecs.imwrite(tempPath + Constant.TEMP_CHAR_DILATE, threshold); // 提取外部轮廓 List<MatOfPoint> contours = Lists.newArrayList(); Imgproc.findContours(threshold, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE); Vector<Rect> charRect = new Vector<Rect>(); // 字符轮廓集合 Mat dst; dst = inMat.clone(); Imgproc.cvtColor(threshold, dst, Imgproc.COLOR_GRAY2BGR); if (debug) {
时间: 2023-12-20 18:04:39 浏览: 36
这段代码是一个字符分割的函数,输入参数包括原始图像、车牌颜色、是否开启调试模式和临时文件保存路径。主要功能是对车牌图像进行预处理,包括切换到灰度图、二值化、边缘腐蚀、错切校正、垂直方向投影、字符分割、边缘膨胀和提取外部轮廓等步骤,最终输出字符轮廓集合。
在函数中,首先根据车牌颜色确定字符个数,然后将原始图像转换为灰度图并进行高斯模糊。接着根据不同车牌颜色使用不同的二值化方法,输出二值图并进行边缘腐蚀。然后进行错切校正,根据垂直方向投影进行精确定位,并根据垂直投影和垂直分割线进行字符分割,去掉上下边框和铆钉干扰。最后进行边缘膨胀,还原腐蚀操作产生的影响,并提取外部轮廓,输出字符轮廓集合。如果开启了调试模式,还会输出中间过程的图像以便调试。
相关问题
代码具体算法解释public static int DEFAULT_MORPH_SIZE_WIDTH = 10; public static int DEFAULT_MORPH_SIZE_HEIGHT = 10; // 大于1 public static Mat morphologyClose(Mat inMat, Mat dst, Boolean debug, String tempPath) { Size size = new Size(DEFAULT_MORPH_SIZE_WIDTH, DEFAULT_MORPH_SIZE_HEIGHT); Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, size); Imgproc.morphologyEx(inMat, dst, Imgproc.MORPH_CLOSE, kernel); debugImg(debug, tempPath, "close", dst); return dst; }
这段代码是用于进行形态学闭运算操作的函数。具体的算法流程如下:
1. 定义默认的形态学操作核大小,即DEFAULT_MORPH_SIZE_WIDTH和DEFAULT_MORPH_SIZE_HEIGHT。
2. 根据默认的核大小创建一个矩形结构元素kernel,这里使用的是MORPH_RECT。
3. 使用OpenCV中的morphologyEx函数进行形态学闭运算,将输入矩阵inMat进行闭运算,得到输出矩阵dst,这里使用的是MORPH_CLOSE。
4. 如果debug参数为true,将dst保存到临时文件夹中,文件名为"close"。
5. 返回输出矩阵dst。
形态学闭运算是一种常用的图像形态学操作,其作用是将图像中小的空洞填平并将小的物体连接成大的物体。在这个函数中,我们使用矩形结构元素进行闭运算操作,可以改变结构元素的形状和大小来达到不同的效果。
代码解释public static void hasPlate(Vector<Mat> inMat, Vector<Mat> dst, Boolean debug, String tempPath) { int i = 0; for (Mat src : inMat) { if (src.rows() == Constant.DEFAULT_HEIGHT && src.cols() == Constant.DEFAULT_WIDTH) { // 尺寸限制; 已经结果resize了,此处判断一下 Mat samples = SVMTrain.getFeature(src); float flag = svm.predict(samples); if (flag == 0) { // 目标符合 dst.add(src); ImageUtil.debugImg(true, tempPath, "platePredict", src); Imgcodecs.imwrite(tempPath + i++ + "_" + Constant.TEMP_PREDICATE, src); } } } }
这段代码是一个车牌识别的功能实现。它的输入是一组图像(inMat),输出是一组识别出来的车牌图像(dst)。具体的实现过程如下:
1. 首先对每张图像进行尺寸限制判断,判断其是否符合默认的车牌尺寸(即Constant.DEFAULT_HEIGHT和Constant.DEFAULT_WIDTH)。
2. 如果符合尺寸要求,则调用SVMTrain.getFeature()方法获取该图像的特征向量。
3. 通过调用svm.predict()方法,对该特征向量进行预测,并得到一个标志值flag。
4. 如果flag等于0,表示该图像识别为车牌,则将其添加到输出列表dst中,并将其保存到本地磁盘中。
5. 最后,如果debug参数为true,则调用ImageUtil.debugImg()方法显示该图像。
需要注意的是,该代码依赖于SVMTrain类和ImageUtil类。其中,SVMTrain类用于训练和加载SVM分类器模型,ImageUtil类用于图像的读取、保存和显示。