如何从带有蒙版的轮廓图像中获取像素值? [英] How to get pixel value from the contoured image with mask?

查看:78
本文介绍了如何从带有蒙版的轮廓图像中获取像素值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I tried to extract average pixel values (R, G, B) from the contoured image. However, my problem is when I applied the code below, something strange values were observed.

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;

}

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

And I got the correct images for the result like below.

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

I want to read pixel values only for yellow part, not for outside of mask.

我还有另一个代码可以读取黄色部分的像素值,但是结果也一样.

And I have another code for read out pixel values in the yellow parts, but it showed the same result.

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
  • Your variables names and Mat types are at least confusing. Use proper names for the variables, and use Mat_<T> whenever possible (I'd say always).
  • To get the mean you should divide by the number of pixels in the mask, not by total number of pixels.
  • you should consider using cv::mean
  • you need cv::waitKey() to actually see your 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();
}

这篇关于如何从带有蒙版的轮廓图像中获取像素值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆