C++ OpenCV:获取 3 通道 RGB 图像,拆分通道并仅使用 R+G 查看图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20341910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV: Taking a 3 channel RGB image, splitting channels and viewing an image with only R+G
提问by Sriharsha
I wanted to look at only the R+G channels in an RGB image because I get better contrasts to detect an object when the Blue channel is removed. I used OpenCV to split the channels,but while merging the same after setting the blue channel to 0, my code doesn't compile.
我只想查看 RGB 图像中的 R+G 通道,因为当蓝色通道被移除时,我可以获得更好的对比度来检测对象。我使用 OpenCV 来拆分通道,但是在将蓝色通道设置为 0 后合并相同的通道时,我的代码无法编译。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image,fin_img;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
// Show our image inside it.
// Create Windows
namedWindow("Red",1);
namedWindow("Green",1);
namedWindow("Blue",1);
// Create Matrices (make sure there is an image in input!)
Mat channel[3];
imshow( "Original Image", image );
// The actual splitting.
split(image, channel);
channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0
//Merging red and green channels
merge(channel,image);
imshow("R+G", image);
waitKey(0);//Wait for a keystroke in the window
return 0;
}
Could I have any feedback on where I'm going wrong? I suspect it is with setting the blue channel to 0. Is there any better way to set it to 0?Is there a way to use cvMixChannels() to do this?
我可以对我出错的地方有任何反馈吗?我怀疑是将蓝色通道设置为 0。有没有更好的方法将其设置为 0?有没有办法使用 cvMixChannels() 来做到这一点?
回答by Haris
You need to change these lines
您需要更改这些行
channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0
//Merging red and green channels
merge(channel,image);
to
到
channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0
//Merging red and green channels
merge(channel,3,image);
Edit
编辑
As per your comment here is the full code and result.
根据您的评论,这里是完整的代码和结果。
#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image,fin_img;
image = imread("bgr.png", CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
// Show our image inside it.
// Create Windows
namedWindow("Red",1);
namedWindow("Green",1);
namedWindow("Blue",1);
// Create Matrices (make sure there is an image in input!)
Mat channel[3];
imshow( "Original Image", image );
// The actual splitting.
split(image, channel);
channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0
//Merging red and green channels
merge(channel,3,image);
imshow("R+G", image);
imwrite("dest.jpg",image);
waitKey(0);//Wait for a keystroke in the window
return 0;
}
Source image
源图像
Result without blue component
结果不含蓝色成分
回答by Adi Shavit
The most efficient way to do this is without any splits and merges. This saves both time and memory.
最有效的方法是不进行任何拆分和合并。这样既节省时间又节省内存。
Just bitwise-AND your image with cv::Scalar(0,255,255)
and this will set your blue channel to zero.
只需按位与您的图像与cv::Scalar(0,255,255)
,这会将您的蓝色通道设置为零。
As in: imshow("R+G", src & cv::Scalar(0,255,255));
.
如:imshow("R+G", src & cv::Scalar(0,255,255));
。
回答by Sriharsha
Alright, I got to work using mixChannels():I have attached an addition to the code snippet above:
好的,我开始使用 mixChannels():我在上面的代码片段中附加了一个附加内容:
Mat gr( image.rows, image.cols, CV_8UC3);
// forming an array of matrices is a quite efficient operation,
// because the matrix data is not copied, only the headers
Mat out[] = {gr};
// bgr[1] -> gr[1],
// bgr[2] -> gr[2],
int from_to[] = {1,1, 2,2 };
mixChannels( &image, 1, out, 2, from_to, 2 );
imshow("R+G",gr);
Thanks Harsha
谢谢哈沙
回答by sturkmen
another way is subtracting Scalar(255,0,0)
from source image
另一种方法是Scalar(255,0,0)
从源图像中减去
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char **argv)
{
Mat src = imread(argv[1], CV_LOAD_IMAGE_COLOR);
imshow("src", src );
src -= Scalar(255,0,0);
imshow("Green and Red channels", src );
waitKey();
return 0;
}