Android:使用JavaCV进行形状检测
我是JavaCV新手。我试图检测图像中最大的矩形,并在原始图像上用颜色勾勒出它的轮廓。我张贴代码下面,我已经尝试,但它不工作。我正在正确地获取Android:使用JavaCV进行形状检测,android,opencv,image-processing,javacv,edge-detection,Android,Opencv,Image Processing,Javacv,Edge Detection,我是JavaCV新手。我试图检测图像中最大的矩形,并在原始图像上用颜色勾勒出它的轮廓。我张贴代码下面,我已经尝试,但它不工作。我正在正确地获取边缘检测图像。我得到了4个角点。只是cvdrawine不起作用。如果我遗漏了什么,请帮助我: OnClick我正在处理图像并在ImageView上再次显示它的按钮。 在按钮的onClickListener中: if ((new File(path + "trial.jpg")).exists()) { opencv_core.IplImage ori
边缘检测图像。我得到了4个角点。只是cvdrawine
不起作用。如果我遗漏了什么,请帮助我:
OnClick
我正在处理图像并在ImageView
上再次显示它的按钮。
在按钮的onClickListener
中:
if ((new File(path + "trial.jpg")).exists()) {
opencv_core.IplImage originalImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_IMWRITE_JPEG_QUALITY);
opencv_core.IplImage iplImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
opencv_core.IplImage edgeDetectedImage = applyCannyRectangleEdgeDetection(iplImage, 80);
opencv_core.CvSeq largestContour = findLargestContour(edgeDetectedImage);
opencv_core.CvPoint[] cvPoints = new opencv_core.CvPoint[4];
for(int i=0; i<largestContour.total();i++)
{
opencv_core.CvPoint cvPoint = new opencv_core.CvPoint(cvGetSeqElem(largestContour, i));
cvPoints[i] = cvPoint;
}
cvDrawLine(originalImage, cvPoints[0], cvPoints[1], opencv_core.CvScalar.YELLOW, 10, 10, 10);
cvDrawLine(originalImage, cvPoints[1], cvPoints[2], opencv_core.CvScalar.YELLOW, 10, 10, 10);
cvDrawLine(originalImage, cvPoints[2], cvPoints[3], opencv_core.CvScalar.YELLOW, 10,10, 10);
cvDrawLine(originalImage, cvPoints[3], cvPoints[0], opencv_core.CvScalar.YELLOW, 10, 10,10);
opencv_imgcodecs.cvSaveImage(path + "img1.jpg", originalImage);
if ((new File(path + "img1.jpg").exists())) {
imageView.setImageDrawable(Drawable.createFromPath(path + "img1.jpg"));
}
}
方法缩尺图像(IplImage,int)
方法findLargestContour(IplImage)
对不起,这应该在评论,但我没有足够的声誉。我从你的代码中可以看到,canny应用于缩小的图像,轮廓也是如此。您正在原始图像上绘制线条(未按百分比缩小),因此它看起来自然不正确(如果它看起来不正确,但正在绘制某些东西)。否则,你应该提到图像的颜色空间,这对绘画来说无关紧要,但对canny来说却很重要 我从缩小的图像中提取点并在图像上绘制。所有的行动都是为了得到这4个角点。利用这些点,我在原始图像上画线。你们所说的,虽然尺寸在原始图像上不合适,但至少应该在图像上画一些东西。在我这里,没有任何东西是画在图像上的。你能张贴图像和角点吗?如果没有,您是否用图像验证了矩形角点的坐标?因为从您的代码中,看起来轮廓是从原始图像的0.8大小的图像中提取的,您正在绘制该图像。另外,您使用的是什么版本的OpenCV?
private opencv_core.IplImage applyCannyRectangleEdgeDetection(opencv_core.IplImage iplImage, int percent) {
opencv_core.IplImage destImage = downScaleImage(iplImage, percent);
OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
Frame grayImageFrame = converterToMat.convert(destImage);
opencv_core.Mat grayImageMat = converterToMat.convertToMat(grayImageFrame);
GaussianBlur(grayImageMat, grayImageMat, new opencv_core.Size(5, 5), 0.0, 0.0, BORDER_DEFAULT);
destImage = converterToMat.convertToIplImage(grayImageFrame);
cvErode(destImage, destImage);
cvDilate(destImage, destImage);
cvCanny(destImage, destImage, 20, 55);
return destImage;
}
private opencv_core.IplImage downScaleImage(opencv_core.IplImage srcImage, int percent) {
opencv_core.IplImage destImage = cvCreateImage(cvSize((srcImage.width() * percent) / 100, (srcImage.height() * percent) / 100), srcImage.depth(), srcImage.nChannels());
cvResize(srcImage, destImage);
return destImage;
}
private opencv_core.CvSeq findLargestContour(opencv_core.IplImage edgeDetectedImage) {
opencv_core.IplImage foundContoursOfImage = cvCloneImage(edgeDetectedImage);
opencv_core.CvMemStorage memory = new opencv_core.CvMemStorage().create();
opencv_core.CvSeq contours = new opencv_core.CvSeq();
cvFindContours(foundContoursOfImage, memory, contours, Loader.sizeof(opencv_core.CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, new opencv_core.CvPoint(0, 0));
int maxWidth = 0;
int maxHeight = 0;
opencv_core.CvRect contr = null;
opencv_core.CvSeq seqFound = null;
opencv_core.CvSeq nextSeq;
for (nextSeq = contours; nextSeq != null; nextSeq = nextSeq.h_next()) {
contr = cvBoundingRect(nextSeq, 0);
if ((contr.width() >= maxWidth) && (contr.height() >= maxHeight)) {
maxHeight = contr.height();
maxWidth = contr.width();
seqFound = nextSeq;
}
}
opencv_core.CvSeq result = cvApproxPoly(seqFound, Loader.sizeof(opencv_core.CvContour.class), memory, CV_POLY_APPROX_DP, cvContourPerimeter(seqFound) * 0.1, 0);
return result;
}