我从这张图片开始:
然后我应用了 Canny 边缘检测器,例如:
Mat originalMatGreyScale = new Mat();
Imgproc.cvtColor(originalPhotoMat, originalMatGreyScale, Imgproc.COLOR_BGR2GRAY);
Mat edgesMat = new Mat();
Imgproc.Canny(originalMatGreyScale, edgesMat , 50, 70);
我有:
然后我找到了一个轮廓列表(contours
)Imgproc.findContours()
。然后我做了一些编码来(1)找到最大轮廓的区域(maximumContourArea
)(2)从contours
任何面积小于的轮廓中删除maximumContourArea
。问题底部给出的代码。
我调用通过在原始图像上Imgproc.drawContours()
绘制绿色(剩余)轮廓
for (int contourIndex = 0; contourIndex < contours.size(); contourIndex++) {
Imgproc.drawContours(originalPhotoMat, contours, contourIndex, new Scalar(0, 255, 0));
}
我所期待的是所有这些小污迹和噪音的轮廓都应该从轮廓列表中删除contours
,但我仍然得到了这个垫子(在这些小污迹周围也绘制了绿色轮廓):
此外,Log.i()
以下代码中的消息打印:
最初的轮廓数:27
处理后的轮廓数:27
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(edgesMap, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
Log.i(TAG, "Number of contours initially: " + contours.size());//check
double maximumContourArea = 0;
Iterator<MatOfPoint> contoursIterator = contours.iterator();
while(contoursIterator.hasNext()) {
MatOfPoint nextContour = contoursIterator.next();
double nextContourArea = Imgproc.contourArea(nextContour);
if (nextContourArea > maximumContourArea) {
maximumContourArea = nextContourArea;
}
}
while(contoursIterator.hasNext()) {
MatOfPoint nextContour = contoursIterator.next();
if (Imgproc.contourArea(nextContour) < maximumContourArea*(10 / 100)) {
contours.remove(contours.indexOf(nextContour));
}
}
Log.i(TAG, "Number of contours after processing: " + contours.size());//check
编辑:
我替换
(10/100)
为0.1
,实际上为了清楚起见,我决定在0.5
这个例子中使用。这样,所有小于最大轮廓面积一半的轮廓都应该被删除。因此,在这里和那里的一些
Log.i
语句之后,我意识到第二个 while 循环没有被执行。经过一番摆弄Iterator
然后下台foreach
循环,我得到了ConcurrentModificationException
,所以我终于发现解决方案是一个for
循环,如下所示。
问题:(a)我仍然得到相同Mat
的 s,而如果您查看以下代码片段以及此页面底部的 logcat 输出中maximumContourArea
的 s 和s 的值currentContourArea
,您会注意到只有一个轮廓,具有面积的1719.0
应该保留,所有其他的都应该删除。(b) 查看以下代码后的 Logcat 输出。
代码更改:
Log.i(TAG, "PNM Number of contours initially: " + contours.size());//check
double maximumContourArea = 0;
for (int currentContour=0; currentContour<contours.size(); currentContour++) {
double currentContourArea = Imgproc.contourArea(contours.get(currentContour));
if (maximumContourArea < currentContourArea) {
maximumContourArea = currentContourArea;
}
}
Log.i(TAG, "PNM maximumContourArea: " + maximumContourArea);//check
Log.i(TAG, "PNM maximumContourArea*.5: " + maximumContourArea*0.5);//check
for (int currentContour=0; currentContour<contours.size(); currentContour++) {
double currentContourArea = Imgproc.contourArea(contours.get(currentContour));
Log.i(TAG, "PNM currentContourArea: " + currentContourArea);//check
if (currentContourArea < maximumContourArea*0.5) {
contours.remove(currentContour);
}
}
Log.i(TAG, "PNM Number of contours after processing: " + contours.size());//check
Logcat 输出:
04-21 12:09:59.955: I/MainActivity(9983): PNM Number of contours initially: 27
04-21 12:09:59.957: I/MainActivity(9983): PNM maximumContourArea: 1992.0
04-21 12:09:59.957: I/MainActivity(9983): PNM maximumContourArea*.5: 996.0
04-21 12:09:59.958: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.958: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 34.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 40.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 2.5
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.960: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.961: I/MainActivity(9983): PNM currentContourArea: 0.5
04-21 12:09:59.961: I/MainActivity(9983): PNM currentContourArea: 1719.0
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 35.5
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 105.0
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 29.5
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 47.0
04-21 12:09:59.962: I/MainActivity(9983): PNM Number of contours after processing: 14
好的,我替换contours.remove(currentContour);
为,Log.i(TAG, "PNM A contour with an area of " + Imgproc.contourArea(contours.remove(currentContour))
+ " is being removed.");
因为ArrayList
'remove()
方法返回被删除的东西(轮廓)。(来源)
我也在currentContour--;
此声明之后添加。
以下是 Logcat 消息:
04-21 14:15:19.824: I/MainActivity(11125): PNM Number of contours: 27
04-21 14:15:19.824: I/MainActivity(11125): PNM maximumContourArea: 1992.0
04-21 14:15:19.824: I/MainActivity(11125): PNM maximumContourArea*.5: 996.0
04-21 14:15:19.824: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.824: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 18.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 18.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 34.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 34.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 40.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 40.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 2.5
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 2.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 4.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 4.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 32.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 32.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 11.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 11.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 1719.0
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 35.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 35.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 59.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 59.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 105.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 105.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 1992.0
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 29.5
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 29.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 259.5
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 259.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 47.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 47.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 38.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 38.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM Number of contours after processing: 2
^ 似乎正在工作。现在唯一存在的问题是,为什么当最后一次执行以在原始图像上绘制绿色轮廓时,我要绘制所有轮廓(甚至是那些围绕着那些 lil 污迹的轮廓) 。drawContours()