0

我正在尝试将一个 pgm 文件 [只是一个像素矩阵,设置行和设置列] 放入一个数组中,水平翻转它,然后再次输出。这就是我阅读它的方式:

bool PgmPicture::readPgmFile(string inputFile)
{
    stringstream ss;
    string line = "";
    int magicNumber;
    ifstream pgmIn;
    pgmIn.open(inputFile.c_str());
if (pgmIn.fail()) { //makes sure that itemList opened okay.
    perror(inputFile.c_str());
    return false;
}
    getline(pgmIn,line);
    pgmIn >> numRows >> numCols >> magicNumber;
    for(int row = 0; row < numRows ; row++) {
    for (int col = 0; col < numCols  ; col++) {
        pgmIn >> picture[row][col]; //this array only contains pixel values, no headers or flags.
    }
}
return true;
}  

所以基本上,图片的第二行包含 2 个值:行和列。例如,300 和 500 表示图片有 300 行和 500 列。如您所见,上面的函数将该行读入 numRows 和 numCols。

在后面的函数中,我试图通过交换像素对来水平翻转图片(例如,最右边的像素与第一个像素,最右边的像素减去第一个像素 + 1 等到中间。 )

这是我的功能:

void PgmPicture::hflip(){
int tmp;
for(int row = 0; row < numRows  ; row++) {
    for (int col = 0; col < numCols  ; col++) {
            tmp = picture[row][col];
            picture[row][col] = picture[numRows - 1 - row][col];
            picture[numRows -1  - row][col] = tmp;
    }
  }
}

这有什么问题?它只是输出与原始图片完全相同的图片。它应该像我描述的那样逐行切换每个元素。你们能不能用新鲜的眼光来看看这个?我已经追踪了一段时间,但我无法弄清楚。

编辑: 我将代码更改为:

int tmp;
for(int row = 0; row < numRows  ; row++) {
    for (int col = 0; col < numCols/2 ; col++) {
            tmp = picture[row][col];
            picture[row][col] = picture[row][numCols - 1 - col];
            picture[row][numCols - 1 - col] = tmp;
    }
}

我只是得到一个乱码。这是原件: http: //i493.photobucket.com/albums/rr294/Jamlegend/mammoth_zps31b72d88.png 和后面的图片:http: //i493.photobucket.com/albums/rr294/Jamlegend/after_zpsdf1a8b40.png

4

5 回答 5

0

那个“乱码”看起来像是用错误的 x 大小绘制的图像。看来您已经交换了 numRows 和 numCols。PGM 格式首先将大小定义为 WIDTH,然后是 HEIGHT。您将 WIDTH 表示为图片的列。

负片起作用的原因是您以相同的顺序写回像素,所以没关系。您真正关心像素位置的任何事情都是错误的。

改为这样做:

pgmIn >> numCols >> numRows >> magicNumber;
于 2014-11-20T14:28:17.327 回答
0

我可能会做这样的事情:

#include <algorithm>

void hflip()
{
    for(int row = 0; row < numRows; ++row)
        std::reverse(picture[row], picture[row] + numCols);
}
于 2014-11-19T21:18:51.967 回答
0

从这行代码:

        tmp = picture[row][col];
        picture[row][col] = picture[numRows - 1 - row][col];
        picture[numRows -1  - row][col] = tmp;

我会说:您正在将顶部像素与底部像素交换,将顶部 1 与底部 1 交换,依此类推。你说你想用右像素交换左边。您的行应如下所示:

        tmp = picture[row][col];
        picture[row][col] = picture[row][numCols - 1 - col];
        picture[row][numCols - 1 - col] = tmp;

试试这个,它可以解决你的问题。也许您没有看到它,因为您的图像具有相同的顶部和底部?当有图像处理代码时,包含图像(结果和输入)通常是一个好主意。

于 2014-11-19T20:59:56.450 回答
0

这个:

picture[row][col] = picture[numRows - 1 - row][col];
picture[numRows -1  - row][col] = tmp;

应该是这样的:

picture[row][col] = picture[row][numCols - 1 - col];
picture[row][numCols - 1 - col] = tmp;

并且您将需要遍历一半的列,否则您将再次切换所有内容。

for (int col = 0; col < numCols / 2; col++)
于 2014-11-19T21:00:52.233 回答
0

您只需要遍历数组的一半。否则,您将交换元素两次!

于 2014-11-19T21:02:14.633 回答