Ask Your Question
0

How can I perform arithmetic operations with pixel

asked 2016-07-21 09:40:32 -0600

ritaplfigueiredo gravatar image

updated 2016-07-22 04:26:29 -0600

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[0];
                int int_blue = (int) blue;
                uchar green = intensity.val[1];
                int int_green = (int) green;
                uchar red = intensity.val[2];
                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[0] = l1;
                intensity.val[1] = l2;
                intensity.val[2] = 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 flag offensive close merge delete

Comments

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

berak gravatar imageberak ( 2016-07-22 04:59:28 -0600 )edit

1 answer

Sort by » oldest newest most voted
2

answered 2016-07-21 09:56:04 -0600

berak gravatar image

updated 2016-07-22 05:56:05 -0600

  • 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.
  • [edit] pixel order is BGR in opencv, not RGB

[edit]

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[3];
    split(imgf, chn);
    // (R-G)^2
    Mat rg = chn[2] - chn[1];
    multiply(rg,rg,rg);
    // (R-B)^2
    Mat rb = chn[2] - chn[0];
    multiply(rb,rb,rb);
    // (G-B)^2
    Mat gb = chn[1] - chn[0];
    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[1];
    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;
}
edit flag offensive delete link 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!

ritaplfigueiredo gravatar imageritaplfigueiredo ( 2016-07-21 10:11:43 -0600 )edit

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

ritaplfigueiredo gravatar imageritaplfigueiredo ( 2016-07-21 10:56:13 -0600 )edit

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

berak gravatar imageberak ( 2016-07-21 11:23:22 -0600 )edit

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

berak gravatar imageberak ( 2016-07-21 11:25:17 -0600 )edit

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

ritaplfigueiredo gravatar imageritaplfigueiredo ( 2016-07-22 04:27:36 -0600 )edit
1

Thank you so much, it solves my main goal!!

ritaplfigueiredo gravatar imageritaplfigueiredo ( 2016-07-26 09:28:15 -0600 )edit

Question Tools

1 follower

Stats

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

Seen: 2,453 times

Last updated: Jul 22 '16