我试图从轮廓图像中提取平均像素值(R,G,B)。但是,我的问题是当我应用下面的代码时,观察到一些奇怪的值。

int main(){
cv::Mat star = imread("C:\\Users\\PC\\Desktop\\star\\starcircle.png");
cv::Mat mask = cv::Mat::zeros(star.rows, star.cols, CV_8UC1);
cv::Mat frame;
double b, g, r = 0.0;

cv::imshow("Original", star);

cv::cvtColor(star, frame, CV_BGR2HSV);

cv::inRange(frame, cv::Scalar(29, 220, 220), cv::Scalar(30, 255, 255), mask);

cv::imshow("mask", mask);

cv::Mat result = cv::Mat(star.rows, star.cols, CV_8UC1, star.type());
result.setTo(cv::Scalar(0, 0, 0));

star.copyTo(result, mask);

cv::Scalar temp = mean(mask);

cout << "avg_R: " << temp[2] << " \n"; // red value
cout << "avg_G: " << temp[1] << " \n"; // green value
cout << "avg_B: " << temp[0] << " \n\n"; // blue value

cv::imshow("result", result);
cv::waitKey(-1);
return 0;

}

我得到了正确的图像,如下所示。

c&#43;&#43; - 如何使用蒙版从轮廓图像中获取像素值?-LMLPHP

我只想读取黄色部分的像素值,而不要读取蒙版外部的像素值。

我还有另一个代码可以读取黄色部分的像素值,但结果却相同。
int main(){
cv::Mat star = imread("C:\\Users\\PC\\Desktop\\star\\starcircle.png");
cv::Mat mask = cv::Mat::zeros(star.rows, star.cols, CV_8UC1);
cv::Mat frame;
double b, g, r = 0.0;

cv::imshow("Original", star);

cv::cvtColor(star, frame, CV_BGR2HSV);

cv::inRange(frame, cv::Scalar(29, 220, 220), cv::Scalar(30, 255, 255), mask);

cv::imshow("mask", mask);

cv::Mat result = cv::Mat(star.rows, star.cols, CV_8UC1, star.type());
result.setTo(cv::Scalar(0, 0, 0));

star.copyTo(result, mask);

int hei = star.rows;
int wid = star.cols;

int corow = hei * wid;

double b, g, r = 0.0;

for (int x = 0; x < hei; x++) {
    for (int y = 0; y < wid; y++) {
        if (mask.at<unsigned char>(x, y) > 0) {
            b += result.at<Vec3b>(x, y)[0];
            g += result.at<Vec3b>(x, y)[1];
            r += result.at<Vec3b>(x, y)[2];

        }
        else {

        }


    }
}

cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
cout << "avg_R: " << r / corow << " \n"; // red value
cout << "avg_G: " << g / corow << " \n"; // green value
cout << "avg_B: " << b / corow << " \n\n"; // blue value

}

请帮助我修改错误。

先感谢您。

最佳答案

一些东西:

  • 您的变量名称和Mat类型至少令人困惑。为变量使用适当的名称,并尽可能使用Mat_<T>(我会一直说)。
  • 要获得均值,应将其除以蒙版中的像素数,而不是除以像素总数。
  • 您应该考虑使用cv::mean
  • 您需要cv::waitKey()才能实际看到自己的cv::imshow

  • 检查代码:
    #include <opencv2\opencv.hpp>
    
    int main()
    {
        cv::Mat3b star = cv::imread("path/to/image");
        cv::imshow("Original", star);
    
        cv::Mat3b hsv;
        cv::cvtColor(star, hsv, cv::COLOR_BGR2HSV);
    
        cv::Mat1b mask;
        cv::inRange(hsv, cv::Scalar(29, 220, 220), cv::Scalar(30, 255, 255), mask);
        cv::imshow("mask", mask);
    
        // Change to 'false' to see how to use the 'cv::mask' approach
        if (true)
        {
            double blue, green, red = 0.0;
            int counter = 0;
            for (int r = 0; r < star.rows; r++)
            {
                for (int c = 0; c < star.cols; c++)
                {
                    if (mask(r, c) > 0)
                    {
                        ++counter;
                        blue += star(r, c)[0];
                        green += star(r, c)[1];
                        red += star(r, c)[2];
                    }
                }
            }
    
            // Avoid division by 0
            if (counter > 0)
            {
                blue /= counter;
                green /= counter;
                red /= counter;
            }
    
            std::cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
            std::cout << "avg_R: " << red << " \n";
            std::cout << "avg_G: " << green << " \n";
            std::cout << "avg_B: " << blue << " \n\n";
        }
        else
        {
            cv::Scalar mean_value = cv::mean(star, mask);
            double blue = mean_value[0];
            double green = mean_value[1];
            double red = mean_value[2];
    
            std::cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
            std::cout << "avg_R: " << red << " \n"; // red value
            std::cout << "avg_G: " << green << " \n"; // green value
            std::cout << "avg_B: " << blue << " \n\n"; // blue value
        }
        cv::waitKey();
    }
    

    10-08 08:24
    查看更多