OpenCV彩色图像灰色问题

时间:2016-04-20 14:46:33

标签: c++ image opencv

我是 OpenCV 的新手,我正试图从目录中获取图像,使其成为黑白(灰度),然后将其写入另一个文件。但输出图像与我的预期完全不同。也许你可以帮助我并在代码中指出错误?

#include <iostream>
#include <opencv2/opencv.hpp>
#include <conio.h>
#include <string.h>
#include <string>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <stdio.h>
#include <stdlib.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

using namespace std;

void faktorial(int InSize, char *DataIn, char *DataOut)// заголовок функции
{
    for(int i = 0,  j = 0; i < InSize; i += 4, j++)
    {
        DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2]) / 3;
    }

}

int main() 
{        
        char* c = "E:\henrik-evensen-castle-valley-v03.jpg";

        printf("Input source of image\n Example of right directory file: E:\henrik-evensen-castle-valley-v03.jpg\n Your try:\n");
        char *tbLEN;
        tbLEN = new char [1024];

        cin.getline(tbLEN,1024);

        cout << tbLEN;


        IplImage* image;
        image = cvLoadImage(tbLEN, 1);
        int height1 = image->height;
        int width1 = image->width;
        int step = image->widthStep;
        int SizeIn = step*height1;
        char* DatIn = image->imageData;

        IplImage *image2 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
        char* DatOut = image2->imageData;

        faktorial(SizeIn, DatIn, DatOut);

        cvNamedWindow("Imagecolor");
        cvShowImage("Imagecolor", image);

        cvNamedWindow("Gray");
        cvShowImage("Gray", image2);
        cvWaitKey(0);
        return 0;
}

Input Image Output Image

修改 我不需要CvtColor函数,我需要使用那个因子函数。

3 个答案:

答案 0 :(得分:1)

试试cvtColor(src, bwsrc, CV_RGB2GRAY); http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html(寻找cvtColor)。

答案 1 :(得分:1)

faktorial中,您假设您有3个频道。因此,您需要将i增加3,而不是增加4.此外,您需要将char*数据转换为uchar*数据,以便积累正常:

你最终得到:

void faktorial(int InSize, uchar *DataIn, uchar *DataOut)
{
    for (int i = 0, j = 0; i < InSize; i += 3, j++)
    {
        DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2]) / 3;
    }
}

您可以轻松地将其扩展到多个渠道,例如:

void faktorial2(int InSize, int nChannels, uchar *DataIn, uchar *DataOut)
{
    for (int i = 0, j = 0; i < InSize; i += nChannels, j++)
    {
        int accum = 0;
        for (int c = 0; c < nChannels; ++c)
        {
            accum += DataIn[i + c];
        }
        DataOut[j] = uchar(accum / nChannels);
    }
}

您通常还需要考虑图像步幅:

void faktorial3(int rows, int cols, int in_step, int in_channels, int out_step, uchar *in, uchar *out)
{
    for (int r = 0; r < rows; ++r)
    {
        for (int c = 0; c < cols; ++c)
        {
            int accum = 0;
            for (int i = 0; i < in_channels; ++i)
            {
                accum += in[r*in_step + c * in_channels + i];
            }
            out[r*out_step + c] = uchar(accum / in_channels);
        }
    }
}

这里是调用的完整代码:

#include <opencv2/opencv.hpp>
using namespace std;

void faktorial3(int rows, int cols, int in_step, int in_channels, int out_step, uchar *in, uchar *out)
{
    for (int r = 0; r < rows; ++r)
    {
        for (int c = 0; c < cols; ++c)
        {
            int accum = 0;
            for (int i = 0; i < in_channels; ++i)
            {
                accum += in[r*in_step + c * in_channels + i];
            }
            out[r*out_step + c] = uchar(accum / in_channels);
        }
    }
}

void faktorial(int InSize, uchar *DataIn, uchar *DataOut)
{
    for (int i = 0, j = 0; i < InSize; i += 3, j++)
    {
        DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2]) / 3;
    }

}

void faktorial2(int InSize, int nChannels, uchar *DataIn, uchar *DataOut)
{
    for (int i = 0, j = 0; i < InSize; i += nChannels, j++)
    {
        int accum = 0;
        for (int c = 0; c < nChannels; ++c)
        {
            accum += DataIn[i + c];
        }
        DataOut[j] = uchar(accum / nChannels);
    }
}

int main()
{
    char tbLEN[] = "D:\\SO\\img\\barns.jpg";

    IplImage* image;
    image = cvLoadImage(tbLEN, 1);

    IplImage *image2 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);

    int height1 = image->height;
    int width1 = image->width;
    int step = image->widthStep;
    int SizeIn = step*height1;
    int nChannels = image->nChannels;
    uchar* DatIn = (uchar*)image->imageData;
    uchar* DatOut = (uchar*)image2->imageData;

    faktorial(SizeIn, DatIn, DatOut);
    //faktorial2(SizeIn, nChannels, DatIn, DatOut);
    //faktorial3(image->height, image->width, image->widthStep, image->nChannels, image2->widthStep, (uchar*)image->imageData, (uchar*)image2->imageData);

    cvNamedWindow("Imagecolor");
    cvShowImage("Imagecolor", image);

    cvNamedWindow("Gray");
    cvShowImage("Gray", image2);
    cvWaitKey(0);
    return 0;
}

请记住,C api已经过时了。 您应该切换到C ++ api。

答案 2 :(得分:0)

您的const remove = (dom, key, value) => { if (!dom) return; // List Level if (Immutable.List.isList(dom)) { let index = dom.findIndex(function (item) { return item.get(key) === value; }); if (index >= 0) return dom.delete(index); return dom.map((item) => remove(item, key, value)); } // Children of the list let ch = dom.get(CHILDREN_ATTRIBUTE); if (ch) { let chIndex = ch.findIndex(function (item) { return item.get(key) === value; }); if (chIndex >= 0) { return dom.set(CHILDREN_ATTRIBUTE, ch.delete(chIndex)); } // We are here, let us try the children's children return dom.set(CHILDREN_ATTRIBUTE, dom.get(CHILDREN_ATTRIBUTE) .map((v) => remove(v, key, value))); } return dom; }; 适用于每像素4个字节的图片(并未考虑可能的线路填充)。

从JPG图像加载每像素3个字节,这就是为什么你看到4个移位的鬼影。 您可以修改faktorial或仅将加载的图像转换为4字节格式

faktorial