gpt4 book ai didi

android - 为什么 OpenCV4Android 的 pointPolygonTest() 方法为每个像素返回-1?

转载 作者:行者123 更新时间:2023-12-02 17:46:17 25 4
gpt4 key购买 nike

在以下代码中,我执行了以下步骤:

  • 从 sdcard 加载图像。

  • enter image description here
  • 将其转换为 HSV 格式。
  • 二手 inRange功能来掩盖红色。

  • enter image description here
  • 二手 findContours找到轮廓。
  • 从这些轮廓中找到最大的轮廓。
  • 使用 boundingRect 在最大轮廓周围创建 ROI和 submat职能。

  • enter image description here
  • 将此 ROI Mat 转换为 HSV 格式。

  • enter image description here
  • 遍历 ROI Mat,并检查每个像素是否位于最大轮廓内。 我用的方法pointPolygonTest找出来,但它返回 -1对于每个像素,从 Log.i 中可以看出输出 I have pasted here .问题是为什么?我该如何纠正这一点。
    private Scalar detectColoredBlob() {
    rgbaFrame = Highgui.imread("/mnt/sdcard/DCIM/rgbaMat4Mask.bmp");

    Mat hsvImage = new Mat();
    Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV);
    Highgui.imwrite("/mnt/sdcard/DCIM/hsvImage.bmp", hsvImage);// check

    Mat maskedImage = new Mat();
    Core.inRange(hsvImage, new Scalar(0, 100, 100), new Scalar(10, 255, 255), maskedImage);
    Highgui.imwrite("/mnt/sdcard/DCIM/maskedImage.bmp", maskedImage);// check

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(maskedImage, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    // \/ We will use only the largest contour. Other contours (any other possible blobs of this color range) will be ignored.
    MatOfPoint largestContour = contours.get(0);
    double largestContourArea = Imgproc.contourArea(largestContour);
    for (int i = 1; i < contours.size(); ++i) {// NB Notice the prefix increment.
    MatOfPoint currentContour = contours.get(i);
    double currentContourArea = Imgproc.contourArea(currentContour);
    if (currentContourArea > largestContourArea) {
    largestContourArea = currentContourArea;
    largestContour = currentContour;
    }
    }
    MatOfPoint2f largestContour2f = new MatOfPoint2f(largestContour.toArray());// Required on Line 289. See http://stackoverflow.com/questions/11273588/how-to-convert-matofpoint-to-matofpoint2f-in-opencv-java-api

    Rect detectedBlobRoi = Imgproc.boundingRect(largestContour);
    Mat detectedBlobRgba = rgbaFrame.submat(detectedBlobRoi);
    Highgui.imwrite("/mnt/sdcard/DCIM/detectedBlobRgba.bmp", detectedBlobRgba);// check

    Mat detectedBlobHsv = new Mat();
    Imgproc.cvtColor(detectedBlobRgba, detectedBlobHsv, Imgproc.COLOR_BGR2HSV);
    Highgui.imwrite("/mnt/sdcard/DCIM/roiHsv.bmp", detectedBlobHsv);// check

    for (int firstCoordinate = 0; firstCoordinate < detectedBlobHsv.rows(); firstCoordinate++) {
    for (int secondCoordinate = 0; secondCoordinate < detectedBlobHsv.cols(); secondCoordinate++) {
    Log.i(TAG, "HAPPY " + Arrays.toString(detectedBlobHsv.get(firstCoordinate, secondCoordinate)));
    if (Imgproc.pointPolygonTest(largestContour2f, new Point(firstCoordinate, secondCoordinate), false) == -1) {
    Log.i(TAG, "HAPPY ....................... OUTSIDE");
    }
    }
    }
    Highgui.imwrite("/mnt/sdcard/DCIM/processedcontoured.bmp", detectedBlobHsv);// check


  • 编辑:

    我这样做是因为我需要计算位于轮廓内的像素的平均 HSV 颜色(即最大红色 Blob 的平均 HSV 颜色)。如果我计算了 ROI 的平均颜色 detectedBlobHsv通过正常的公式,我会做类似的事情
    Scalar averageHsvColor= new Scalar(256);
    Scalar sumHsvOfPixels = new Scalar(256);
    sumHsvOfPixels = Core.sumElems(detectedBlobHsv);
    int numOfPixels = detectedBlobHsv.width() * detectedBlobHsv.height();
    for (int channel=0; channel<sumHsvOfPixels.val.length; channel++) {
    averageHsvColor = sumHsvOfPixels.val[channel]/numOfPixels;
    }

    所以这里有人(可能是你?)曾建议我一种方法来排除我的轮廓之外的像素。我会像这样实现:
    //Giving pixels outside contour of interest an HSV value of `double[]{0,0,0}`, so that they don't affect the computation of `sumHsvOfPixels` while computing average, 
    //and while keeping track of the number of pixels removed from computation this way, so we can subtract that number from the `$numOfPixels` during computation of average.
    int pixelsRemoved = 0;
    for (int row=0; row<detectedBlobHsv.rows(); row++) {
    for (int col=0; col<detectedBlobHsv.cols(); col++) {
    if (Imgproc.pointPolygonTest(largestContour2f, new Point(row, col), false) == -1) {
    detectedBlobHsv.put(row, col, new double[]{0,0,0});
    pixelsRemoved++;
    }
    }
    }

    然后计算平均值
    Scalar averageHsvColor= new Scalar(256);
    Scalar sumHsvOfPixels = new Scalar(256);
    sumHsvOfPixels = Core.sumElems(detectedBlobHsv); //This will now exclude pixels outside the contour
    int numOfPixels = ( detectedBlobHsv.width()*detectedBlobHsv.height() )-pixelsRemoved;
    for (int channel=0; channel<sumHsvOfPixels.val.length; channel++) {
    averageHsvColor = sumHsvOfPixels.val[channel]/numOfPixels;
    }

    编辑 1:

    在以下方法结束时,我创建了带有 MatOfPoint 列表的掩码s 仅包含最大轮廓。当我把它写到 SDCard 时,我得到了

    enter image description here

    我不知道我在哪里搞砸了!
    private Scalar detectColoredBlob() {
    //Highgui.imwrite("/mnt/sdcard/DCIM/rgbaFrame.jpg", rgbaFrame);// check
    rgbaFrame = Highgui.imread("/mnt/sdcard/DCIM/rgbaMat4Mask.bmp");


    //GIVING A UNIFORM VALUE OF 255 TO THE V CHANNEL OF EACH PIXEL (255 IS THE MAXIMUM VALUE OF V ALLOWED - Simulating a maximum light condition)
    for (int firstCoordinate = 0; firstCoordinate < rgbaFrame.rows(); firstCoordinate++) {
    for (int secondCoordinate = 0; secondCoordinate < rgbaFrame.cols(); secondCoordinate++) {
    double[] pixelChannels = rgbaFrame.get(firstCoordinate, secondCoordinate);
    pixelChannels[2] = 255;
    rgbaFrame.put(firstCoordinate, secondCoordinate, pixelChannels);
    }
    }


    Mat hsvImage = new Mat();
    Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV);
    Highgui.imwrite("/mnt/sdcard/DCIM/hsvImage.bmp", hsvImage);// check


    Mat maskedImage = new Mat();
    Core.inRange(hsvImage, new Scalar(0, 100, 100), new Scalar(10, 255, 255), maskedImage);
    Highgui.imwrite("/mnt/sdcard/DCIM/maskedImage.bmp", maskedImage);// check


    // Mat dilatedMat = new Mat();
    // Imgproc.dilate(maskedImage, dilatedMat, new Mat());
    // Highgui.imwrite("/mnt/sdcard/DCIM/dilatedMat.jpg", dilatedMat);// check


    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(maskedImage, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    //FINDING THE BIGGEST CONTOUR
    // \/ We will use only the largest contour. Other contours (any other possible blobs of this color range) will be ignored.
    MatOfPoint largestContour = contours.get(0);
    double largestContourArea = Imgproc.contourArea(largestContour);
    for (int i = 1; i < contours.size(); ++i) {// NB Notice the prefix increment.
    MatOfPoint currentContour = contours.get(i);
    double currentContourArea = Imgproc.contourArea(currentContour);
    if (currentContourArea > largestContourArea) {
    largestContourArea = currentContourArea;
    largestContour = currentContour;
    }
    }


    Rect detectedBlobRoi = Imgproc.boundingRect(largestContour);
    Mat detectedBlobRgba = rgbaFrame.submat(detectedBlobRoi);
    Highgui.imwrite("/mnt/sdcard/DCIM/detectedBlobRgba.bmp", detectedBlobRgba);// check


    Mat detectedBlobHsv = new Mat();
    Imgproc.cvtColor(detectedBlobRgba, detectedBlobHsv, Imgproc.COLOR_BGR2HSV);
    Highgui.imwrite("/mnt/sdcard/DCIM/roiHsv.bmp", detectedBlobHsv);// check

    List<MatOfPoint> largestContourList = new ArrayList<>();
    largestContourList.add(largestContour);

    Mat roiWithMask = new Mat(detectedBlobHsv.rows(), detectedBlobHsv.cols(), CvType.CV_8UC3);
    roiWithMask.setTo(new Scalar(0,0,0));
    Imgproc.drawContours(roiWithMask, largestContourList, 0, new Scalar(0, 255, 255), -1);//TODO Using -1 instead of CV_FILLED.
    Highgui.imwrite("/mnt/sdcard/DCIM/roiWithMask.bmp", roiWithMask);// check


    // CALCULATING THE AVERAGE COLOR OF THE DETECTED BLOB
    // STEP 1:
    double [] averageHsvColor = new double[]{0,0,0};
    int numOfPixels = 0;
    for (int firstCoordinate = 0; firstCoordinate < detectedBlobHsv.rows(); ++firstCoordinate) {
    for (int secondCoordinate = 0; secondCoordinate < detectedBlobHsv.cols(); ++secondCoordinate) {

    double hue = roiWithMask.get(firstCoordinate, secondCoordinate)[0];
    double saturation = roiWithMask.get(firstCoordinate, secondCoordinate)[1];
    double value = roiWithMask.get(firstCoordinate, secondCoordinate)[2];

    averageHsvColor[0] += hue;
    averageHsvColor[1] += saturation;
    averageHsvColor[2] += value;

    numOfPixels++;
    }
    }
    averageHsvColor[0] /= numOfPixels;
    averageHsvColor[1] /= numOfPixels;
    averageHsvColor[1] /= numOfPixels;



    return new Scalar(averageHsvColor);
    }

    编辑 2:

    我纠正了我的 3 channel 蒙版并制作了单 channel 蒙版
    Mat roiMask = new Mat(rgbaFrame.rows(), rgbaFrame.cols(), CvType.CV_8UC1);
    roiMask.setTo(new Scalar(0));
    Imgproc.drawContours(roiMask, largestContourList, 0, new Scalar(255), -1);

    这导致了正确的 roiMask :

    enter image description here

    然后,在评论前 // CALCULATING THE AVERAGE COLOR OF THE DETECTED BLOB ,我补充说:
    Mat newImageWithRoi = new Mat(rgbaFrame.rows(), rgbaFrame.cols(), CvType.CV_8UC3);
    newImageWithRoi.setTo(new Scalar(0, 0, 0));
    rgbaFrame.copyTo(newImageWithRoi, roiMask);
    Highgui.imwrite("/mnt/sdcard/DCIM/newImageWithRoi.bmp", newImageWithRoi);//check

    这导致:

    enter image description here

    现在我又不知道如何进行。 :秒

    最佳答案

    您不需要使用 pointPolygonTest ,因为你已经有了面具。

    您可以简单地总结掩码上的值。类似于(无法测试):

    // Initialize at 0!!!
    Scalar averageHsvColor= new Scalar(0,0,0);

    int numOfPixels = 0;

    for(int r=0; r<detectedBlobHsv.height(); ++r)
    {
    for(int c=0; c<detectedBlobHsv.width(); ++c)
    {
    if( /* value of mask(r,c) > 0 */)
    {
    int H = // get H value of pixel at (r, c)
    int S = // get S value of pixel at (r, c)
    int V = // get V value of pixel at (r, c)

    // Sum values
    averageHsvColor[0] += H;
    averageHsvColor[1] += S;
    averageHsvColor[2] += V;

    // Increment number of pixels inside mask
    numOfPixels ++;
    }
    }
    }

    // Compute average
    averageHsvColor[0] /= numOfPixels ;
    averageHsvColor[1] /= numOfPixels ;
    averageHsvColor[2] /= numOfPixels ;

    关于android - 为什么 OpenCV4Android 的 pointPolygonTest() 方法为每个像素返回-1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34775659/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com