【问题标题】:C++, Bilinear Interpolation to patch holes on the enlarged bitmap ImageC ++,双线性插值以修补放大的位图图像上的孔
【发布时间】:2016-10-07 05:53:12
【问题描述】:

为了将位图图像放大 3 倍,我实现了这段代码并发现了漏洞。我决定使用双线性插值,上面这些是修补最近像素的代码,其权重的计算方式与此代码类似。输出[j*hInfo.biWidth+i] =图像[3/2*j*hInfo.biWidth + 3/1*i].
逻辑很简单,所以我认为它会正常工作,我很确定,但是 Image 的结果看起来像一个西瓜,就像我的感觉一样,请看一下代码。任何 cmets 都欢迎。谢谢阅读。

void main() 
{
BITMAPFILEHEADER hf;
BITMAPINFOHEADER hInfo;
RGBQUAD hRGB[256];
FILE *fp;
fp = fopen("input.bmp", "rb");
if(fp == NULL) return;
fread(&hf, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&hInfo, sizeof(BITMAPINFOHEADER), 1, fp);
fread(hRGB, sizeof(RGBQUAD), 256, fp);
hInfo.biWidth *=3;
hInfo.biHeight *=3;
int ImgSize = hInfo.biWidth * hInfo.biHeight;

BYTE *Image = (BYTE *) malloc(ImgSize);
BYTE *Output = (BYTE *)malloc(ImgSize);
fread(Image, sizeof(BYTE), ImgSize, fp);
fclose(fp);
double Sx, Sy;
scanf("%lf", & Sx);// scaling factor x : 3
scanf("%lf", & Sy);// scaling factor y : 3

for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if(j*Sx < hInfo.biWidth && i*Sy<hInfo.biHeight)

Output[(int)(i*Sy)*hInfo.biWidth+(int)(j*Sx)] = Image[i*hInfo.biWidth + j];
    }
}


// horizontally executed first. 

for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if( j%3 == 1)
        {
            Output[i*hInfo.biWidth+j] = (int)Image[( (hInfo.biWidth*(1/3) + j+2) + ( hInfo.biWidth* (2/3) + (j-1) ) )]; 
        }
        else if( j%3 == 2 )
        {
            Output[i*hInfo.biWidth+j] = (int)Image[( (hInfo.biWidth*(2/3) + j+1) + ( hInfo.biWidth* (1/3) + (j-2) ) )];
        }
        else if(  j%3 ==1 && j+2 >= hInfo.biWidth)
        {
            Output[i*hInfo.biWidth+j] = Image[i*hInfo.biWidth + (j-2)] ;
        }
        else if(  j%3 ==2 && j+1 >= hInfo.biWidth)
        {
            Output[i*hInfo.biWidth+j] = Image[i*hInfo.biWidth + (j-2)] ;
        }

    }
}


// vertically executed last 
for(int j= 0 ; j < hInfo.biWidth; j++){

    for(int i=0; i < hInfo.biHeight; i++){

        if( j%3 == 1)
        {
            Output[j*hInfo.biWidth+i] = Image[hInfo.biWidth*(1/3) + (i+2) + hInfo.biWidth* (2/3) + (i-1);   
        }
        else if( j%3 == 2 )
        {
            Output[j*hInfo.biWidth+i] = Image[hInfo.biWidth*(2/3) + (i+1) + hInfo.biWidth* (1/3) + (i-2)];
        }
        else if(  j%3 ==1 && j+2>=hInfo.biWidth)
        {
            Output[j*hInfo.biWidth+i] = Image[j*hInfo.biWidth + (i-2)] ;
        }
        else if(  j%3 ==2 && j+1>=hInfo.biWidth)
        {
            Output[j*hInfo.biWidth+i] = Image[j*hInfo.biWidth + (i-2)] ;
        }

    }
}

fp = fopen("output.bmp", "wb");
fwrite(&hf, sizeof(BYTE), sizeof(BITMAPFILEHEADER), fp);
fwrite(&hInfo, sizeof(BYTE), sizeof(BITMAPINFOHEADER), fp);
fwrite(hRGB, sizeof(RGBQUAD), 256, fp);
fwrite(Output, sizeof(BYTE),ImgSize, fp);
fclose(fp);
free(Image);
free(Output);
}

【问题讨论】:

  • void main 从来不是有效的 C 或 C++。它使读者更难复制和粘贴您的代码来尝试它,因为只有一个常用的编译器接受它,并且它教会了初学者的坏习惯。请不要使用void main 发布代码;已更正。
  • 另外,请在发布之前使用一致的缩进格式化您的代码。 AStyle 等免费工具可以为您做到这一点。许多程序员的编辑器也可以为你做这件事,但最好的是在你编写代码时正确地格式化代码。我建议您现在正确缩进代码并重新发布。没有任何其他更改。
  • 看来你设置了Output[x] = Image[y],即插值不是真的插值,而是另一个位置的另一个点。它不应该是Output[x] = Image[y]*(1/3) + Image[z]*(2/3) 之类的东西,即Image 应该(至少)在右侧出现两次吗?
  • 请注意,例如1/3 如果像整数除法那样做为 0。
  • 如果四个ifs 是if (j%3==1) ... else if(j%3==1 &amp;&amp; ...) 也是流,所以else if 部分永远不会是真的

标签: c++ bmp bilinear-interpolation


【解决方案1】:

感谢大家,我终于完成了代码。是的,我不需要已经受 for 循环条件限制的 else if 。

    for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if( j%3 == 1)
        {
            Output[i*hInfo.biWidth+j] = (int)Output[i*hInfo.biWidth+j-1]*2/3+(int)Output[i*hInfo.biWidth+j+2]*1/3;
        }
        else if( j%3 == 2 )
        {
            Output[i*hInfo.biWidth+j] = (int)Output[i*hInfo.biWidth+j-1]*1/3 + (int)Output[hInfo.biWidth*i + (j-2)]*2/3;
        }

    }
}
for(int i= 0 ; i < hInfo.biHeight; i++){    
    for(int j= 0; j < hInfo.biWidth; j++){      
        if( j%3 == 1)
        {
            Output[j*hInfo.biWidth+i] = (int)Output[(j-1)*hInfo.biWidth+i]*2/3+(int)Output[(j+2)*hInfo.biWidth+i]*1/3;
        }
        else if( j%3 == 2 )
        {
            Output[j*hInfo.biWidth+i] = (int)Output[(j-1)*hInfo.biWidth+i]*1/3 + (int)Output[hInfo.biWidth*(j-2) + i]*2/3;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2015-11-14
    • 2015-06-03
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多