如何使用cvAvg或平均值计算集合ROI中像素的“单个”平均值/平均值?

时间:2013-07-30 14:56:20

标签: opencv

我有一个尺寸为320x320像素的阈值图像。通过设置ROI,我以20x20像素的块循环遍历整个图像。我需要找到每个块的平均值。所以我将这些图像块传递给函数'cvAvg'。我面临以下问题。

  1. 'cvAvg'的返回类型是'CvScalar',它有4个双打。我无法解释文档中的CvScalar。我只需要像“浮动”或“双倍”格式的像素的单个平均值,我需要做出其他决定。如何从函数返回值中提取单个值。我不想迭代所有像素并找到平均值。我想以20x20的块进行处理。 例如:如果在20x20的块中200像素是白色且200像素是黑色,我希望能够提取单个值,以便我可以判断该块具有50%的白色像素并且我认为是平均值/平均值这将是一个很好的了解方式。

  2. 我创建了一个CvScalar类型的变量来检索和打印函数'cvAvg返回的值。但是阈值图像的所有值都是相同的

  3. 0.000000 255.000000 0.000000 0.000000

    0.000000 255.000000 0.000000 0.000000

    0.000000 255.000000 0.000000 0.000000

    0.000000 255.000000 0.000000 0.000000

    并且这通过256次循环遍历图像的所有块,这是不正确的,因为阈值图像具有白色和黑色的不同部分。这里发生了什么?代码如下。 imgGreenThresh是为绿色设定阈值的“二进制图像”。

    IplImage* imgDummy = cvCreateImage(cvGetSize(imgGreenThresh), 8, 1);    //Create a dummy image of the same size as thresholded image
    cvCopy(imgGreenThresh, imgDummy);                                       //Copy the thresholded image for further operations
    CvRect roi;                                                             //Rectangular ROI
    CvSize size;
    int r, c, N=20;
    int count = 0;
    float LaserState[16][16];                                               //Create 16x16 matrix to hold the laser state values.
    CvScalar meanValue;                                                     // individual windows mean value
    
    size = cvGetSize(imgDummy);                                             //returns image ROI, in other words, height and width of matrix
                                                                            //Iteratively send the different ROIs for processing.
    for (r = 0; r < size.height; r += N)
        for (c = 0; c < size.width; c += N)
        {
            count++;
            roi.x = c;
            roi.y = r;
            roi.width = (c + N > size.width) ? (size.width - c) : N;
            roi.height = (r + N > size.height) ? (size.height - r) : N;
            cvSetImageROI(imgDummy, roi);
            meanValue = cvAvg(imgDummy);
            printf("%f\t%f\t%f\t%f\n", meanValue);
            cvResetImageROI(imgDummy);
    
        }
    //cvResetImageROI(imgDummy);                                                //Do not forget to reset ROIs
    

    谢谢!

    苏德赫。

2 个答案:

答案 0 :(得分:5)

我可以在以下链接中找到计算单个频道平均值的解决方案: Average values of a single channel

对于您的情况,您有ROI而不是单个频道。在OpenCV中,ROI也是一个Mat对象(如果您使用的是OpenCV的C ++代码),您可以将其传递给cv :: mean(...)函数以获取Scalar对象。只有该对象的第一个条目才能正确设置为ROI的平均值,这就是您想要的值。有关详细信息,请参阅上面的链接。

答案 1 :(得分:0)

我创建了另一个变量SingleMeanValue并指定了第0个值meanValue(CvScalar类型)。由于某种原因,meanvalue [0]不能像@lightalchemist所提议的那样工作。我不知道这是否应该有用,我对此很新。也许它适用于C ++,但在C中这可能是正确的方法。

double SingleMeanValue = meanValue.val [0];工作及以下是更新代码的输出。

0.000000 0.000000 35.062500 247.350000 109.012500 137.700000 243.525000 51.000000 0.000000 0.000000等..

感谢@lightalchemist的帮助