How to get negative of each channel (Red, Green, Blue) in RGB image?

How to get negative of each channel (Red, Green, Blue) in RGB image?

Problem Description:

I am trying to get negative of negative of each channel (Red, Green, Blue) in RGB image.
Simply put :

  1. If value of red channel in an RGB image is ‘r’, I am looking to get r’=255-r.
  2. Repeat this process for green and blue as well.
  3. Finally merge r’,g’ and b’ to display the image.

Below is the code I have written but it gives:

Process terminated with status -1073741819

as output. Also please see detailed output.

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
//#include<filesystem>

int main()
{
   Mat myImage;//declaring a matrix to load the image//
   Mat different_Channels[3];//declaring a matrix with three channels//
   String imgPath = "C:/Users/tusha/Desktop/ResearchPractise/testNegativeImage/RGB.jpg";
   myImage= imread(imgPath,IMREAD_UNCHANGED);//loading the image in myImage matrix//
   split(myImage, different_Channels);//splitting images into 3 different channels//
   Mat b = different_Channels[0];//loading blue channels//
   Mat g = different_Channels[1];//loading green channels//
   Mat r = different_Channels[2];//loading red channels//
   //for red channel
   for (int y = 0; y < myImage.rows; y++) {
        for (int x = 0; x < myImage.cols; x++) {
            //Retrieving the values of a pixel
            int pixelr = r.at<uchar>(x,y);
            pixelr = 255-pixelr;
            r.at<uchar>(x,y)=pixelr;
            }
   }

   //for green channel
   for (int y = 0; y < myImage.rows; y++) {
        for (int x = 0; x < myImage.cols; x++) {
            //Retrieving the values of a pixel
            int pixelg = g.at<uchar>(x,y);
            pixelg = 255-pixelg;
            g.at<uchar>(x,y)=pixelg;
            }
   }
   //for blue channel
   for (int y = 0; y < myImage.rows; y++) {
        for (int x = 0; x < myImage.cols; x++) {
            //Retrieving the values of a pixel
            int pixelb = b.at<uchar>(x,y);
            pixelb = 255-pixelb;
            b.at<uchar>(x,y)=pixelb;
            }
   }
   vector<Mat> channels;
   channels.push_back(r);
   channels.push_back(g);
   channels.push_back(b);
   Mat negImage;
   merge(channels,negImage);
   cout<<"Negative image";
   namedWindow("Negative",WINDOW_NORMAL);
   imshow("Negative",negImage);
   return 0;
}

Solution – 1

The main issue:
As you can see in the cv::Mat::at documentation, you should
first pass the col (i.e. your y coordinate), and then the row (i.e. your x coordinate).

Therefore all the 6 lines referring to:

at<uchar>(x,y)

Should be changed to:

at<uchar>(y,x)

Assuming your image is not a square, inverting the coordinated as you did is not only semantically wrong but will also result in access via invalid indices (causing access violation).

Regarding the result display:
You can also remove the WINDOW_NORMAL argument you pass to cv::namedWindow in order to see the result image in its actual size.
In addition you should add a call to cv::waitKey (e.g. cv::waitKey(0);) after it to keep the window opened and process GUI events.

Note that using cv::Mat::at to traverse all pixels is quite inefficient. A more efficient approach would be to use cv::Mat::ptr per row to get a pointer to the row data, and then traverse it using pointer arithmetics.

A side note: better to avoid using namespace std – see here Why is "using namespace std;" considered bad practice?. A similar argument can be applied to using namespace cv;.

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject