List<MatOfPoint> contours = new ArrayList<>(); 遍历
时间: 2023-08-04 12:11:49 浏览: 81
遍历 `contours` 中的所有元素的代码可以使用 Java 的 for-each 循环实现,示例代码如下:
```
for (MatOfPoint contour : contours) {
// 在这里对每个 contour 进行操作
}
```
这段代码会将 `contours` 中的每个元素都赋值给 `contour` 变量,然后在循环体中对其进行操作。注意,`contour` 的类型是 `MatOfPoint`,即一个由点组成的矩阵。你可以通过 `contour.toArray()` 方法获取矩阵中的所有点,进而对它们进行处理。
相关问题
代码解释:public static Vector<Mat> findPlateByContours(Mat src, Mat inMat, Vector<Mat> dst, Boolean debug, String tempPath) { // 灰度图 Mat gray = new Mat(); ImageUtil.gray(inMat, gray, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_GRAY, gray); // 高斯模糊 Mat gsMat = new Mat(); ImageUtil.gaussianBlur(gray, gsMat, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_GAUSSIAN, gsMat); // Sobel 运算,得到图像的一阶水平方向导数 Mat sobel = new Mat(); ImageUtil.sobel(gsMat, sobel, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_SOBEL, sobel); // 图像进行二值化 Mat threshold = new Mat(); ImageUtil.threshold(sobel, threshold, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_THRESHOLD, threshold); // 使用闭操作 同时处理一些干扰元素 Mat morphology = threshold.clone(); ImageUtil.morphologyClose(threshold, morphology, debug, tempPath); // 闭操作 Imgcodecs.imwrite(tempPath + Constant.TEMP_CLOSE, morphology); // 边缘腐蚀,边缘膨胀,可以多执行两次 morphology = ImageUtil.erode(morphology, debug, tempPath, 4, 4); Imgcodecs.imwrite(tempPath + Constant.TEMP_ERODE, morphology); morphology = ImageUtil.dilate(morphology, debug, tempPath, 4, 4, true); Imgcodecs.imwrite(tempPath + Constant.TEMP_DILATE, morphology); // 保存结果到目标文件 // 将二值图像,resize到原图的尺寸; 如果使用缩小后的图片提取图块,可能会出现变形,影响后续识别结果 ImageUtil.enlarge(morphology, morphology, src.size(), debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_RESIZE, morphology); // 获取图中所有的轮廓 List<MatOfPoint> contours = ImageUtil.contours(src, morphology, debug, tempPath); Imgcodecs.imwrite(tempPath + Constant.TEMP_CONTOUR, morphology); // 根据轮廓, 筛选出可能是车牌的图块 Vector<Mat> blockMat = ImageUtil.screenBlock(src, contours, false, debug, tempPath); // 找出可能是车牌的图块,存到dst中, 返回结果 hasPlate(blockMat, dst, debug, tempPath + "contour/"); return dst; }
这段代码实现了一个车牌识别的功能,具体步骤如下:
1. 将输入图像转换为灰度图,并进行高斯模糊,以减少噪声的影响。
2. 对图像进行 Sobel 运算,得到图像的一阶水平方向导数,以便后续进行边缘检测。
3. 对图像进行二值化处理,将图像转为黑白二值图像。
4. 使用闭操作处理图像,以去除一些干扰元素。
5. 对图像进行边缘腐蚀和膨胀操作,以进一步消除干扰元素。
6. 将处理后的图像放大至原图的尺寸,避免后续识别过程中出现变形。
7. 获取图中所有的轮廓,以便后续筛选可能是车牌的图块。
8. 根据轮廓信息,筛选出可能是车牌的图块,并将其存储到目标文件中。
9. 对筛选出的图块进行车牌识别,最终返回识别结果。
该代码段中调用了一些封装好的图像处理函数,包括灰度化、高斯模糊、Sobel 运算、二值化、闭操作、边缘腐蚀和膨胀、轮廓提取等。其中还有一些中间结果写入到文件中,以便调试和观察。最终将识别结果存储在目标文件中,并返回给调用者。
代码解释: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) {
这段代码是一个字符分割的函数,输入参数包括原始图像、车牌颜色、是否开启调试模式和临时文件保存路径。主要功能是对车牌图像进行预处理,包括切换到灰度图、二值化、边缘腐蚀、错切校正、垂直方向投影、字符分割、边缘膨胀和提取外部轮廓等步骤,最终输出字符轮廓集合。
在函数中,首先根据车牌颜色确定字符个数,然后将原始图像转换为灰度图并进行高斯模糊。接着根据不同车牌颜色使用不同的二值化方法,输出二值图并进行边缘腐蚀。然后进行错切校正,根据垂直方向投影进行精确定位,并根据垂直投影和垂直分割线进行字符分割,去掉上下边框和铆钉干扰。最后进行边缘膨胀,还原腐蚀操作产生的影响,并提取外部轮廓,输出字符轮廓集合。如果开启了调试模式,还会输出中间过程的图像以便调试。
阅读全文