我是android新手,我的应用程序在使用drawcontour一段时间后崩溃了。应用程序必须查找最大轮廓并计算其边界框。以下是我的代码示例:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
img_rgb = inputFrame.rgba();
Imgproc.blur(img_rgb, blur, new Size(25,25));
Imgproc.cvtColor(blur, img_gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(img_gray, thres1, 0, 255, Imgproc.THRESH_OTSU);
Imgproc.erode(thres1, erode1, new Mat(), new Point(-1,-1), 3);
Imgproc.dilate(erode1, dilate1, new Mat(), new Point(-1,-1), 2);
Imgproc.erode(dilate1, erode2, new Mat(), new Point(-1,-1), 3);
Imgproc.dilate(erode2, dilate2, new Mat(), new Point(-1,-1), 2);
Imgproc.adaptiveThreshold(dilate2, thres2, 128,Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV,7, 1);
contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(thres2, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
hierarchy.release();
//Imgproc.drawContours(img_rgb, contours, -1, new Scalar(Math.random()*255, Math.random()*255, Math.random()*255));//, 2, 8, hierarchy, 0, new Point());
for(int i = 0;i<contours.size();i++){
double area = Imgproc.contourArea(contours.get(i));
if(area > largest_area){
largest_area = area;
largest_contour_index = i;
bounding_rect = Imgproc.boundingRect(contours.get(i));
}
}
Imgproc.drawContours(img_rgb,contours,largest_contour_index, new Scalar(0,255,0),2);
return img_rgb;
}
答案 0 :(得分:0)
您永远不会重置largest_area
和largest_contour_index
,因此largest_contour_index
可能会引发无效索引。
您只需要在每个循环中重置这些值,并仅在索引有效时绘制轮廓(即,如果找到至少一个轮廓)。根据您的进一步处理,您可能还需要重置bounding_rect
。您可以将boundingRect
调用移出for循环,这样可以避免无用的计算。
代码:
// Reset values at each iteration
largest_area = 0;
largest_contour_index = -1;
for(int i = 0;i<contours.size();i++){
double area = Imgproc.contourArea(contours.get(i));
if(area > largest_area){
largest_area = area;
largest_contour_index = i;
}
}
// Draw only if index is valid
if(largest_contour_index >= 0) {
bounding_rect = Imgproc.boundingRect(contours.get(largest_contour_index));
Imgproc.drawContours(img_rgb,contours,largest_contour_index, new Scalar(0,255,0),2);
}