# 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?

Contents

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";
split(myImage, different_Channels);//splitting images into 3 different 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.