围绕轮廓JavaCV绘制边界框?

时间:2016-07-17 23:33:31

标签: java opencv javacv vision

我想知道如何使用JavaCV在轮廓周围绘制边界框。我知道像素区域和中心点。我还找到了一种找到像素宽度的方法来找到距离。我觉得一个边界框可以更精确地找到像素宽度来找到距离然后我正在做的事情。任何帮助都会很棒,或者如果你知道另一种方法来找到很棒的距离。感谢...

import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.opencv_core.CvMemStorage;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacpp.opencv_videoio.CvCapture;
import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
public class Webcam {
   public static void main(String[] args) throws Exception {
       CvCapture capture = opencv_videoio.cvCreateCameraCapture(0);

       IplImage img1, imghsv, imgbin;
       CvScalar minc = cvScalar(95,125,75,0), maxc = cvScalar(145,255,255,0);
       CvSeq contour1 = new CvSeq(), contour2;
       CvMemStorage storage = CvMemStorage.create();
       CvMoments moments = new CvMoments(Loader.sizeof(CvMoments.class));
       double areaMax = 1000, areaC = 0;
       double m01, m10, m_area, focal, width, obj_width, obj_height;
       double distance;

       //focal is (pixel width * distance in inches) / object width 
       focal = 144.4;
       //Real objects width in inches
       obj_width = 3.5;
     //Real objects height in inches
       obj_height = 3.5;

       int posX=0, posY=0;

       int cRad = 100;

       while(true)
       {
       img1 = opencv_videoio.cvQueryFrame(capture); 
       opencv_imgproc.cvSmooth(img1, img1, CV_MEDIAN, 13, 0, 0, 0);
       imgbin = IplImage.create(cvGetSize(img1), 8, 1);
       imghsv = IplImage.create(cvGetSize(img1), 8, 3);


       if(img1 == null) break;

       cvCvtColor(img1, imghsv, CV_BGR2HSV);
       cvInRangeS(imghsv, minc, maxc, imgbin);

       contour1 = new CvSeq();
       areaMax = 1000;

       cvFindContours(imgbin, storage, contour1, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_LINK_RUNS, cvPoint(0,0));

       contour2 = contour1;

       while(contour1 != null && !contour1.isNull())
       {
           areaC = cvContourArea(contour1, CV_WHOLE_SEQ, 1);

           if(areaC > areaMax)
           {
               areaMax = areaC;
           }

           contour1 = contour1.h_next();
       }

       while(contour2 != null && !contour2.isNull())
       {
           areaC = cvContourArea(contour2, CV_WHOLE_SEQ, 1);

           if(areaC < areaMax)
           {
               cvDrawContours(imgbin, contour2, CV_RGB(0,0,0),CV_RGB(0,0,0),0,CV_FILLED,8,cvPoint(0,0));
           }
           contour2 = contour2.h_next();
       }

       cvMoments(imgbin, moments, 1);
       m10 = cvGetSpatialMoment(moments, 1, 0);
       m01 = cvGetSpatialMoment(moments, 0, 1);
       m_area = cvGetCentralMoment(moments, 0, 0);

       posX = (int) (m10/m_area);
       posY = (int) (m01/m_area);

       if(posX > 0 && posY > 0)
       {
           cRad = (int) (100 / (5000/m_area));
           cvCircle(img1, cvPoint(posX, posY), 5, cvScalar(0,255,0,0), 9, 0, 0);
       }
       //Change numbers after m_area to size of object
       width =  java.lang.Math.sqrt((m_area/(obj_height*obj_width)));

       distance = (obj_width * focal) / width;

       cvFlip(img1, img1, 1);
       cvFlip(imgbin, imgbin , 1);
       opencv_highgui.cvShowImage("Color",img1);
       opencv_highgui.cvShowImage("CF",imgbin);
       char c = (char) opencv_highgui.cvWaitKey(15);
       if(c == 27) break;
       if(c == 'q')
       {
           System.out.print("Width in pixels ");
           System.out.println(width);
           System.out.print("Distance in inches ");
           System.out.println(distance);

       }
       }

   }
}

This is what I have This is what I want 。我能够找到所有蓝色轮廓并将背景变为黑色。我想在蓝色像素周围绘制一个边界框,以帮助更好地找到对象的距离,并确保我们跟踪正确的对象。

1 个答案:

答案 0 :(得分:1)

如果您想围绕轮廓绘制一个 bouding 框,您只需使用:

Rect rect = opencv_imgproc.boundingRect(contour);
opencv_imgproc.rectangle(src, rect, Scalar.GREEN);