Ask Your Question

# How can I perform arithmetic operations with pixel

I have a set of 70 RGB images (argc=71). I wanted to change pixel values according to these formulas:

l1 = (R-G)^2/((R-G)^2 + (R-B)^2 + (G-B)^2);

l2 = (R-B)^2/((R-G)^2 + (R-B)^2 + (G-B)^2);

l3 = (R-G)^2/((G-B)^2 + (R-B)^2 + (G-B)^2);

And then store the new images. The code I tried using c++ is below but I keep getting this error:

SetPixels(99556,0x7fff76450000) malloc: * error for object 0x10a9ce000: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug

Can anyone help me solve this matter?

Thanks in advance!

#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <sstream>
using namespace cv;
using namespace std;
int main(int agra, char** argv){
for(int k=1;k<=argc;k++){

char* imageName = argv[k];
Mat image;
image = imread(imageName,CV_LOAD_IMAGE_UNCHANGED);

uchar l1;
uchar l2;
uchar l3;

for (int i=0; i<=image.rows;i++){
for (int j=0; j<=image.cols; j++){
Vec3b intensity = image.at<Vec3b>(Point(i, j));
uchar blue = intensity.val;
int int_blue = (int) blue;
uchar green = intensity.val;
int int_green = (int) green;
uchar red = intensity.val;
int int_red = (int) red;

int rg = pow(int_red-int_green,2);
int rb = pow(int_red-int_blue,2);
int gb = pow(int_green - int_blue,2);

int int_l1 = rg/(rg+rb+gb);
int int_l2 = rb/(rg+rb+gb);
int int_l3 = gb/(rg+rb+gb);

l1 = (uchar) int_l1;
l2 = (uchar) int_l2;
l3 = (uchar) int_l3;

intensity.val = l1;
intensity.val = l2;
intensity.val = l3;

image.at<Vec3b>(i,j)= intensity;

}
}

stringstream ss;
string name = "l1l2l3image_";
string type = ".jpg";
ss<<name<<(k)<<type;
string filename = ss.str();
ss.str("");
imwrite(filename, image);
}
return 0;
}

edit retag close merge delete

## Comments

int int_l1 = rg/(rg+rb+gb); <-- this integer division will always be 0 ! 

## 1 answer

Sort by » oldest newest most voted
• image.at<Vec3b>(j,i)= intensity; <-- i,j , not j,i (you're probably out of bounds this way)
• please use the c++ headers: #include <opencv2/opencv.hpp> not the deprecated c ones(cv.h, highgui.h)
• in general, - try to avoid per-pixel loops.
•  pixel order is BGR in opencv, not RGB

imho, you have to do this in float space, not in 8u. while i'm at it, one could get rid of the loops, too.

void filter2 (const Mat &image, Mat &out)
{
// convert and split
Mat imgf;
image.convertTo(imgf, CV_32F, 1.0/255.0);
Mat chn;
split(imgf, chn);
// (R-G)^2
Mat rg = chn - chn;
multiply(rg,rg,rg);
// (R-B)^2
Mat rb = chn - chn;
multiply(rb,rb,rb);
// (G-B)^2
Mat gb = chn - chn;
multiply(gb,gb,gb);
// divide by sum
Mat sm = (rg + rb + gb);
divide(rg, sm, rg);
divide(rb, sm, rb);
divide(gb, sm, gb);
// merge and concvert
Mat ch2[] = {rg, rb, gb};
merge(ch2, 3, imgf);
imgf.convertTo(out, CV_8U, 255.0);
}

int main(int agra, char** argv){
String fn="phase1.png";
if (agra>1) fn = argv;
Mat image = imread(fn);
if (image.empty())
{
cerr << "U$)TZ(T§$TI§H";
return 1;
}
Mat result;
filter2(image, result);
imshow("org", image);
imshow("res", result);
waitKey(0);
return 0;
}

more

## Comments

Note taken on the headers (must have learnt using an old tutorial...). Regarding the question itself, I now get the written images all black, any suggestions on that? Thanks for the tips and help!

That is only if I let default options on imread. If I load it unchanged the order will still be RGB, right?

no, you're wrong about that. the order is always BGR. "unchanged" only means, that a possible alpha channel won't get discarded, or a 16bit img won't get converted to 8bit

sidenote: you only have to calculate e.g. pow(R-G,2)`once, not 3 times.

Thanks on the notes! Still can't seem to write the modified images... Is there anything more for me to correct? I have no 'error' message but still nothing happens

1

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2016-07-21 09:40:32 -0500

Seen: 1,745 times

Last updated: Jul 22 '16