无法使用C ++在Matlab上打开重采样图像

时间:2014-06-28 23:46:43

标签: c++ image matlab opencv image-processing

我有一个使用OpenCv编写的C ++代码,它在我的图像上运行良好。但是,因为代码运行时间太长,我决定更改每个图像的尺寸并保存在文件夹中。在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");

编辑:函数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;
} 

编辑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 ++无法打开调整大小的图像。我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:2)

正如我们在评论中所讨论的,在Zernike矩计算代码中,两个最内部的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语句应该可以防止访问图像尺寸之外的像素。在您的代码中,此保护措施不在此处。