分离颜色成分

时间:2014-01-17 10:37:53

标签: c++ c opencv

我正在关注this帖子以找到图片的颜色成分。我以为我将从红色组件开始,然后继续使用其他组件。我写的代码如下。我没有使用Linux,我正在使用Windows。

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,image->nChannels);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            red=pImg[i*image->widthStep + j*image->nChannels + 2];
            pRed[i*image->widthStep + j*image->nChannels + 2]=red;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

  

red = pImg [i * image-&gt; widthStep + j * image-&gt; nChannels + 2];

     

pRed [i * image-&gt; widthStep + j * image-&gt; nChannels + 2] = red;

显示此错误:

  

无法将类型为uchar的值分配给该类型的实体   IplImage结构

我哪里错了?

3 个答案:

答案 0 :(得分:4)

使用C ++:

cv::Mat myImage;
myImage=imread("myImage.jpg");
std::vector<cv::Mat> channels;
cv::split(myImage,channels);
imshow("Red Channel",channels[2]);

答案 1 :(得分:0)

red在此处定义:

IplImage* red=cvCreateImage( ...

看起来您只想要一个单独的颜色值,因此您需要使用一个新变量(我将其命名为redValue以减少混淆)

    for(int j=0;j<image->width;j++)
    {
        uchar redValue=pImg[i*image->widthStep + j*image->nChannels + 2];
        pRed[i*image->widthStep + j*image->nChannels + 2]=redValue;
    }

答案 2 :(得分:-2)

首先:如果你没有被迫使用IplImage,请切换到cv::Mat,因为它更容易使用并理解openCV的新c ++语法!

对于你的问题:如果你只想提取红色通道(像你一样手动提取,openCV可以通过函数调用来实现),试试这个代码:我添加了注释,我改变了一些东西: / p>

我将其用作测试的输入图像:

enter image description here

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    // !!! the image that shall contain the red channel must have number of channels = 1 !!!
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,1);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            // !!! you have to use a variable that holds the value of single channel's pixel, which is uchar in this case (values from 0 to 255)
            uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2];
            // !!! since the red image has only 1 channel, be sure to use the right ->nChannels (from the 'red' image
            pRed[i*red->widthStep + j*red->nChannels]=redVal;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

这应该只显示红色通道作为灰度图像。

对于lena输入图像,结果如下所示:

enter image description here

如果您想以RGB格式显示并关闭其他频道,请尝试以下方法:

#include <opencv\cv.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main(int argc, char**argv)
{
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1);
    // !!! use 3 channels again because we want to display colors
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,3);
    uchar *pImg =(uchar*)image->imageData;
    uchar *pRed=(uchar*)red->imageData;
    for(int i=0;i<image->height;i++)
    {
        for(int j=0;j<image->width;j++)
        {
            // !!! you have to use a variable that holds the value of single channel's pixel, which is uchar in this case (values from 0 to 255)
            uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2];
            // !!! set all channels to zero, except the red channel which is copied. be sure to use the right widthStep 
            pRed[i*red->widthStep + j*red->nChannels + 0]=0;
            pRed[i*red->widthStep + j*red->nChannels + 1]=0;
            pRed[i*red->widthStep + j*red->nChannels + 2]=redVal;
        }
    }
    namedWindow("Display",1);
    cvShowImage("Display",red);
    waitKey(0);
    return 0;
}

对于lena输入图像,结果如下所示:

enter image description here