Передача IplImage * в функцию, оригинал не обновляется

У меня проблемы с передачей параметров IplImage * в функции. Это для школьного проекта, и, к сожалению, я не должен редактировать файлы, которые вызывают мои функции фильтра. В основном изображение вводится как параметр командной строки, затем создается его копия и передается в правильную функцию фильтра, как таковую:

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

А вот код из одного из моих фильтров:

void median (IplImage * image, int k){
cout << "image address: " << &image << endl;
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);  //insertion sort from CSCI362 text, see references
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 becuase the original doesn't seem to get modified
//when converting the Mat back to an IplImage
image = cvCloneImage(&(IplImage)matImage);  //convert backto IplImage for DesktopMain
}

Проблема в том, что отфильтрованное изображение, показанное в основном, не отражает фактическое изображение. Это показывает только оригинальное изображение. Когда я вывожу изображение MatImage в стиле Mat в свою функцию фильтра, оно показывает отфильтрованное изображение. Сразу после того, как я преобразовал обратно в IplImage и установил входной параметр IplImage * равным преобразованной, отфильтрованной версии. Но изменения не отражают изображение, отображаемое в основной функции.

Это затрудняет создание некоторых из моих других фильтров, таких как Gaussian и Sobel, потому что эти фильтры сами вызывают другие функции перед выполнением их манипуляций, и я не получаю отредактированные данные обратно. Есть ли что-то, что мне не хватает, как редактировать переданную переменную IplImage *?

Спасибо заранее за любую помощь!

0

Решение

Вместо этого:

image = cvCloneImage(&(IplImage)matImage);

использовать этот:

cvCopy(&(IplImage)matImage,image);
2

Другие решения

Ваша функция никогда не редактирует переданное изображение.

Эта линия предположительно делает копию изображения.

Mat matImage(image);        //convert IplImage to Mat for work

Тогда ваш код изменяет это matImage копия.

И в конце функции эта локальная копия уничтожается, и IplImage указал на image никогда не был изменен.

Редактировать:
Ответ Вона Катона показывает, как конкретно вы можете решить эту проблему.

3

Для перехода по 3 каналам вы должны использовать итератор:

Mat out;
*********open out********
Mat_<Vec3b>::iterator it = out.begin<Vec3b>();
MatConstIterator_<Vec3b> it_end = out.end<Vec3b>();

for(; it != it_end; ++it)
{
//your 3 channels
(*it)[0] = ...;
(*it)[1] = ....;
(*it)[2] = ......;
}
0
По вопросам рекламы [email protected]