本文介绍了如何从带有蒙版的轮廓图像中获取像素值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我试图从轮廓图像中提取平均像素值(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 useMat_<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 yourcv::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();
}
这篇关于如何从带有蒙版的轮廓图像中获取像素值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!