Не могу открыть пересчитанное изображение на Matlab с C ++

0

У меня есть код C++, написанный с использованием OpenCv, который хорошо работает на моих изображениях. Но, поскольку код занимает слишком много времени, я решил изменить каждый размер изображения и сохранить его в папке. Часть кода, написанного в Matlab, где я переформатирую изображения, выглядит следующим образом:

    %read image  
    image=imread(char(image_name));
    %The image will become 4 times smaller
    img_resized=imresize(image,0.25);  
    %save the image with the same name, but now it is smaller
    C = regexp(char(image_name),'/','split');
    imwrite(img_resized, [name_folder '/' char(C(end))]);

Что действительно странно, когда я запускаю код C++ на этих измененных изображениях, я получаю ошибку ошибки сегментации. Когда я запускаю исходные изображения, код работает хорошо.

Ошибка при возврате кода при изменении размеров изображений. Здесь beach_wood_copy_r8.png - это измененное изображение

  ./zernike beach_wood_copy_r8.png beach_wood_gt_r8.png resu.png
  Reading Images
  Calculating Zernike
  Segmentation fault (core dumped)

И есть часть исходного кода C++, где происходит ошибка:

int main(int argc, char** argv){
  int r, c, nDegree, nBlockSize;
  printf("Reading Images\n");
  BYTE** pSrc = getImage(argv[1], r, c);
  BYTE** pGround = getImage(argv[2], r, c);
  set<pair<int, int>, LessFunctionClass> matchedIndex;
  time_t start_time, end_time, prog_time;   

  start_time = time(NULL);

  nDegree = 6;
  nBlockSize = 24;
  printf("Calculating Zernike\n");
  //error happens here
  calculateZernike(pSrc, r, c, nDegree, nBlockSize);
  printf("Zernike calculated\n");

EDIT: функция getImage находится в следующих строках:

BYTE** getImage(char* fName, int& r, int& c){

IplImage* img = cvLoadImage(fName, CV_LOAD_IMAGE_GRAYSCALE);
int i, j;
BYTE **pSrc;

c = img->width;
r = img->height;

pSrc = new BYTE*[r];

for(i=0; i<r; i++){
    pSrc[i] = new BYTE[c];
}


for(i=0; i<r; i++){
    for(j=0; j<c; j++){
        pSrc[i][j] = img->imageData[i*c + j];
    }
}
cvReleaseImage( &img);
return pSrc;
} 

EDIT 2 Вот где исходный код вычисляет zernike моменты:

void calculateZernike(BYTE **p_block, int r, int c, int degree, int blockSize)
{

int i, j, k, l, m, n, numDegree;
double pi;
pi = acos(-1.0);

COMPLEX ***p_Vnm = getZernikePolynomial(blockSize, degree);
numDegree = 0;
for(i=0; i<degree; i++){
    numDegree += (i/2+1);
}

for(i=0; i<c-blockSize+1; i=i+1){
    for(j=0; j<r-blockSize+1; j=j+1){
        BlockInfo zResult;
        zResult.m_x = i;
        zResult.m_y = j;

        int zDegree = 0;
        for(n=0; n<degree; n++){
            for(m=0; m<=n; m++){
                if( (n-m)%2 == 0 ){
                    COMPLEX sumValue;
                    sumValue.r = 0;
                    sumValue.j = 0; 

                    for(k=0; k<blockSize; k++){
                        for(l=0; l<blockSize; l++){
                            sumValue.r += p_Vnm[zDegree][k][l].r * p_block[j+k][i+l];
                            sumValue.j += p_Vnm[zDegree][k][l].j * p_block[j+k][i+l];
                        }
                    }
                    sumValue.j *= (n+1)/pi;
                    sumValue.r *= (n+1)/pi;

                    double tempMag, tempPhase;
                    tempMag = sqrt(sumValue.j*sumValue.j + sumValue.r*sumValue.r);
                    tempPhase = atan2(sumValue.r, sumValue.j);
                    sumValue.r = tempMag;
                    sumValue.j = tempPhase;



                    zResult.ZMM.push_back(sumValue);
                    zDegree++;
                }
            }
        }

        blockZMMs.push_back(zResult);

    }
}



for (i=0; i<numDegree; i++){
    for(j=0; j<blockSize; j++){
        delete [] p_Vnm[i][j];
    }
    delete [] p_Vnm[i];
}
delete p_Vnm;

return ;

}

Я думаю, что C++ не может открыть измененные изображения. Что я могу сделать, чтобы исправить это?

  • 0
    «C ++ не может открыть измененные изображения» - это чепуха. У меня такое ощущение, что вы получаете доступ к местам, которые не имеют границ на изображениях. Удалось ли изменить r и c после изменения размеров изображений? r и c жестко запрограммированы в вашей C ++ программе? Я не вижу, чтобы r и c читались или устанавливались где-либо, поэтому я предполагаю, что это делается за пределами main .
  • 0
    @rayryeng спасибо за ваш ответ, r anc c получает ширину и высоту изображения соответственно, см. мои правки. Изображение уже изменено, когда я запускаю код, я просто указываю, где находится изображение.
Показать ещё 21 комментарий
Теги:
opencv
image-processing
image

1 ответ

2
Лучший ответ

Как мы уже говорили в комментариях, в коде вычисления моментов Церника, два внутренние большинством for петель пытаются получить доступ к пикселям, которые находятся вне границ в изображении. Чтобы этого избежать, попробуйте написать следующую инструкцию if перед выполнением любых вычислений:

for (k = 0; k < blockSize; k++) {
     for (l = 0; l < blockSize; l++) {
          // Change here
          if (j+k < 0 || j+k >= r || i+l < 0 || i+l >= c) 
             continue;

          sumValue.r += p_Vnm[zDegree][k][l].r * p_block[j+k][i+l];
          sumValue.j += p_Vnm[zDegree][k][l].j * p_block[j+k][i+l];
     }
}

Оператор if в цикле for должен предотвращать доступ к пикселам, которые находятся за пределами размеров изображения. Эта защита не была здесь раньше в вашем коде.

  • 1
    @mad - Круто! Было ли это причиной того, что вы продолжали получать ошибки сегментации?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню