c++imageopencvequalizer

Segmentation error when trying to equalize an image


I've been reading about opencv and I've been doing some exercises, in this case I want to perform an image equalization, I have implemented the following code, but when I execute it I get the following error:

"Segmentation fault (core dumped)"

So I have no idea what is due.

The formula I am trying to use is the following:

equalization

The code is the following:

 #include <opencv2/opencv.hpp>
 #include <opencv2/highgui/highgui.hpp> 
 #include <stdio.h>

 using namespace cv;
 using namespace std;

 void equalization(cv::Mat &image,cv::Mat &green, int m) {
 Mat eqIm;
 int nl= image.rows; // number of lines

int nc= image.cols * image.channels();
for (int j=0; j<nl; j++) {

    uchar* data= image.ptr<uchar>(j);
    uchar* data2= green.ptr<uchar>(j);
    uchar* eqIm= green.ptr<uchar>(j);

    for (int i=0; i<nc; i++) {

        eqIm[i]= data[i]+m-data2[i];

    }
 }
 cv::imshow("Image",eqIm);
 imwrite("eqIm.png",eqIm);
 }

float mean(cv::Mat &image){
   cv:Scalar tempVal = mean( image );
   float myMAtMean = tempVal.val[0];
   cout << "The value is " << myMAtMean;
 }

 int main(int argc, char** argv ){
 Mat dst;
 Mat image= cv::imread("img.jpg");
 Mat green= cv::imread("green.jpg");

 cv::imshow("Image",image);
 float m= mean(image);

 equalization(image,green,m);
 cv::namedWindow("Image");
 cv::imshow("Image",image);
 imwrite("equalizated.png",dst);
 waitKey(0);
 return 0;

}

and the image "Equalization.png" that is written contains nothing


Solution

  • You never initialized Mat eqIm, so when you do cv::imshow("Image", eqIm); imwrite("eqIm.png", eqIm); there is nothing in the mat. https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html

    Also, I should note that you have 2 variables of eqIm. That may be part of the confusion.

    One last thing, in your mean function, you may end up with a recursive function. You should specify what mean function you are using in the mean function you create, i.e.

    float mean(cv::Mat &image) {
    cv:Scalar tempVal = cv::mean(image);
        float myMAtMean = tempVal.val[0];
        cout << "The value is " << myMAtMean;
        return myMAtMean;
    }
    

    The following is something closer to what you are looking for in your equalization function.

    void equalization(cv::Mat &image, cv::Mat &green, int m) {
        Mat eqIm(image.rows,image.cols,image.type());
        int nl = image.rows; // number of lines
        int nc = image.cols * image.channels();
        for (int j = 0; j<nl; j++) {// j is each row
            for (int ec = 0; ec < nc; ec++) {//ec is each col and channels
                    eqIm.data[j*image.cols*image.channels() + ec] = image.data[j*image.cols*image.channels() + ec] + m - green.data[j*image.cols*image.channels() + ec];
            }
        }
        cv::imshow("Image", eqIm);
        imwrite("eqIm.png", eqIm);
    }
    

    I do j*image.cols*image.channels() to step through the entire size of j lines (the number of columns times the number of channels per pixel).