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

Can't open a resampled image on Matlab with C++

本文关键字:新采样 采样 图像 C++ Matlab      更新时间:2023-10-16

我有一个使用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 Imagesn");
  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 Zerniken");
  //error happens here
  calculateZernike(pSrc, r, c, nDegree, nBlockSize);
  printf("Zernike calculatedn");

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这里是计算泽尼克矩的源代码:

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++不能打开调整大小的图像。我能做些什么来解决这个问题?

正如我们在评论中讨论的那样,在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];
     }
}

for循环中的if语句应该防止访问图像尺寸之外的像素。