Passing IplImage* to function, original not getting updated

asked 2013-02-10 10:51:57 -0500

jrpharis gravatar image

I am having trouble passing IplImage* parameters in functions. This is for a school project and unfortunately am not supposed to edit the files doing the calling to my filter functions. In the main, the image is brought in as a command line parameter, then a copy of this is made and passed to the correct filter function, as such:

IplImage * floating = cvCreateImage (cvSize (img->width, img->height), IPL_DEPTH_32F, 3);
cvConvertScale (img, floating, 1/255., 0);

IplImage * filtered;

switch (filter.ImageFormat)
{
  case YUV24:
    filtered = cvCreateImage (cvSize (floating->width, floating->height), IPL_DEPTH_32F, 3);
    cvCvtColor (floating, filtered, CV_BGR2YCrCb);
    break;
  case BGR24:
    filtered = cvCloneImage (floating);
    break;
  case Gray:
    filtered = cvCreateImage (cvSize (floating->width, floating->height), IPL_DEPTH_32F, 1);
    cvCvtColor (floating, filtered, CV_BGR2GRAY);
    break;
}

cvNamedWindow ("original", CV_WINDOW_AUTOSIZE);
cvShowImage ("original", img);

filter.ImageFilter (filtered, p);

if (filter.ImageFormat == YUV24)
{
  cvCvtColor (filtered, filtered, CV_YCrCb2BGR);
}

cvNamedWindow (filterName.c_str(), CV_WINDOW_AUTOSIZE);
cvShowImage (filterName.c_str(), filtered);

And here is the code from one of my filters:

void median (IplImage * image, int k){
  Mat matImage(image);        //convert IplImage to Mat for work
  vector<Mat> bgr_channels;   //vector to hold each channel
  int i,j,m,n;                //row/column indeces
  int kernelSize = (2*k+1)*(2*k+1);
  vector<float> vals(kernelSize); //kernelSized vector to hold all values of image
                                  //within kernel centered at a given pixel
  int vecIndex = 0;   //then sorted to get the median
  int chanIndex = 0;  //index used to for each channel

  //add padding to account for border issues with convolution
  copyMakeBorder( matImage, matImage, k, k, k, k, BORDER_REPLICATE);
  //split channes to do work on individual channels
  split(matImage, bgr_channels);

  for(chanIndex=0; chanIndex < matImage.channels(); chanIndex++){
    //outer loop for scanning entire image
    for(i=k; i<matImage.rows-k; i++)/*image row index*/{
      for(j=k; j<matImage.cols-k; j++)/*image column index*/{
        //inner loop for scanning image only in kernel boundaries
        vecIndex = 0;   //reset vecIndex at start of each kernel loop
        for(m=i-k; m<(i+k+1); m++)/*kernel row index*/{
          for(n=j-k; n<(j+k+1); n++)/*kernel column index*/{                      
            vals[vecIndex++] = bgr_channels[chanIndex].at<float>(m,n);
          }
        }
        insertionSort(vals, 0, vals.size()-1);
        bgr_channels[chanIndex].at<float>(i,j) = vals[vals.size()/2]; 
          //new value chosen from middle element of sorted vector
      }
    }
  }

  merge(bgr_channels, matImage);      //merge channels together
  imshow("Median: Mat", matImage);    //left this in because the original doesn't get modified                                
                                      //when converting the Mat back to an IplImage 
  image = cvCloneImage(&(IplImage)matImage);  //convert backto IplImage for DesktopMain
}

The problem is, that the filtered image shown in the main, does not reflect the actual image. It only shows the original image. When I output put the Mat style image matImage in my filter function, it shows the filtered image. Immediately after I convert back to IplImage and set the IplImage* input parameter equal to the the converted, filtered version. But the changes do not reflect the image displayed in the main function.

This is making it hard to create some of my other filters such as Gaussian and Sobel, because those filters themselves make calls ... (more)

edit retag flag offensive close merge delete