我有一个使用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 ++无法打开调整大小的图像。我该怎么做才能解决这个问题?
答案 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
语句应该可以防止访问图像尺寸之外的像素。在您的代码中,此保护措施不在此处。