在OpenCV中进行RGB图像阈值处理

16

我有一张彩色图像,想在OpenCV中进行二值化处理。我希望的是,如果RGB通道中的任何一个通道低于某个值,将所有通道中的值设为零(即黑色)。

因此,我使用OpenCV的阈值函数:

cv::Mat frame, thresholded
// read frame somewhere, it is a BGR image.
cv::threshold(frame, thresholded, 5, 255, cv::THRESH_BINARY);

所以,我认为这样做的作用是,如果任何一个通道小于5,它会将它们设置为零。然而,它似乎并不起作用。例如,对于一些区域,我只能看到绿色通道,表明并非所有通道都被设置为0。

是否有一种快速使用OpenCV实现此目的的方法?


阈值处理将任何低于5的值设为0,而任何其他值都设为255。这是你想要的吗? - berak
2个回答

31

可以使用函数cv::inRange将彩色图像进行阈值处理。

void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
例如,您可以仅允许介于(0,125,0)和(255,200,255)之间的值,或者允许任何单个通道的值:
cv::Mat image = cv::imread("bird.jpg");

if (image.empty())
{
    std::cout << "> This image is empty" << std::endl;
    return 1;
}

原始图片

cv::Mat output;
cv::inRange(image, cv::Scalar(0, 125, 0), cv::Scalar(255, 200, 255), output);
cv::imshow("output", output);

输出图片


1
又一次通过谷歌搜索“opencv阈值颜色”来到了这里。不错的技巧! - karlphillip

2
简而言之,您需要将图像分成包含三个通道的三个图像,独立地对它们进行阈值处理,然后再将它们合并。
Mat frame,thresholded;
vector<Mat> splited_frame;
//Read your frame
split(frame, splited_frame);
for (size_t i = 0; i < splited_frame.size(); i++)
   threshold(splited_frame[i], splited_frame[i], 5, 255, cv::THRESH_BINARY);
merge(splited_frame,thresholded);

这段代码应该可以做到。 抱歉,我读得太快了。 然后,在 for 循环后你需要稍微修改一下代码。
thresholded = splited_frame[0].clone();
for(size_t i = 1; i < splited_frame.size(); i++) thresholded &= splited_frame[i];
frame &= thresholded;

您需要从三个阈值图像中创建一个掩模,然后将此掩模应用于输入图像。


这样做是否存在问题,因为并非所有通道都会被设置为零。我猜可以在阈值图像上使用按位_AND运算符来生成最终的掩码。 - Luca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接