Ask Your Question

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 =<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;

      <Vec3b>(i,j)= intensity;


        stringstream ss;
        string name = "l1l2l3image_";
        string type = ".jpg";
        string filename = ss.str();
        imwrite(filename, image);
    return 0;
edit retag flag offensive close merge delete


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

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

berak gravatar image

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

  •<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


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];
    // (R-B)^2
    Mat rb = chn[2] - chn[0];
    // (G-B)^2
    Mat gb = chn[1] - chn[0];
    // 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);
    return 0;
edit flag offensive delete link more


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

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

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

Question Tools

1 follower


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

Seen: 2,123 times

Last updated: Jul 22 '16