Search code examples
c++imageopencvmat

OpenCV Mat image to black and white error


I'm trying to proccess the image from the directory, make it black and white (grayscale) and then write it down to another file. I've already done it using C library of OpenCV, here is the code

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

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;
    }

}

int main()
{
    char tbLEN[] = "Assassin.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);

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

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

It works perfectly fine, but since C OpenCV is obsolete, I'm trying to do the same thing with C++, but the output image is quite different from what I expected. Where is the mistake? Also, am I doing right, when creating an empty image using Mat img2(img.rows,img.cols, CV_8UC3)?

Here is the code.

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;
    }

}

int main()
{
        Mat img = imread("Assassin.jpg", CV_LOAD_IMAGE_UNCHANGED);
        if (img.empty())
     {
          cout << "Error : Image cannot be loaded..!!" << endl;
          return -1;
     }

        uchar* DataImg = img.data;

        int Width = img.cols;
        int Height = img.rows;
        int Step = img.step;
        int SizeInImg = Step * Height;
        Mat img2(img.rows,img.cols, CV_8UC3);
        uchar* DataImg2 = img2.data;
        faktorial(SizeInImg, DataImg, DataImg2);


     namedWindow("MyWindow", CV_WINDOW_AUTOSIZE);
     imshow("MyWindow", img2);
}

Input Input

Ouput Output


Solution

  • the problem is here

    Mat img2(img.rows,img.cols, CV_8UC3);
    

    it should be

    Mat img2(img.rows,img.cols, CV_8UC1);
    

    and you should use CV_LOAD_IMAGE_COLOR instead of CV_LOAD_IMAGE_UNCHANGED

    Mat img = imread(argv[1], CV_LOAD_IMAGE_COLOR);