水平翻转数组?
Posted
技术标签:
【中文标题】水平翻转数组?【英文标题】:Horizontally flipping an array? 【发布时间】:2014-11-19 20:51:55 【问题描述】:我正在尝试将一个 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
【问题讨论】:
1- 您没有显示任何输出代码。 2- 你说水平翻转,但你的交换超过了row
索引,这意味着垂直翻转。
picture
的声明是什么,又怎么写出来?
图片是short
数组,1024x1024
PGM 文件可以是 short
数组 - 也可以是 byte
数组。您可以改用 8 位数组再试一次。
@StevenHansen 视情况而定,某些变体包含可能超过 255 的“最大值”,当这种情况发生时,大小会增长到每个像素 2 个字节。如此处所述:netpbm.sourceforge.net/doc/pgm.html
【参考方案1】:
那个“乱码”看起来像是用错误的 x 大小绘制的图像。看来您已经交换了 numRows 和 numCols。 PGM 格式首先将大小定义为 WIDTH,然后是 HEIGHT。您将 WIDTH 表示为图片的列。
负片起作用的原因是您以相同的顺序写回像素,所以没关系。您真正关心像素位置的任何事情都是错误的。
改为这样做:
pgmIn >> numCols >> numRows >> magicNumber;
【讨论】:
你就是那个男人。这让我非常沮丧。非常感谢!有趣的是,我在写回文件的函数中就拥有了这一点,我只是没想到。感谢您的帮助!【参考方案2】:从这行代码:
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;
试试这个,它可以解决你的问题。也许您没有看到它,因为您的图像具有相同的顶部和底部?当有图像处理代码时,包含图像(结果和输入)通常是一个好主意。
【讨论】:
【参考方案3】:这个:
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++)
【讨论】:
好的,我对我的第一篇文章进行了编辑。新的输出只是一个大乱码!除了可能 numrows 和 numcols 错误之外,我想不出任何理由为什么会这样关闭,但我在处理之前将它们打印出来并且它们是正确的。 可能您的 PGM 文件包含 BYTE 值,也可能包含 SHORT 值。您是否检查并适应了这两种类型? pgm 文件只是一个以空格分隔的 0 到 255 之间的像素值列表。读入工作正常,我还有一个简单的“制作负函数,从 255 中减去每个值,使图片的负面版本。这很好用。【参考方案4】:您只需要遍历数组的一半。 否则你会交换元素两次!
【讨论】:
【参考方案5】:我可能会这样做:
#include <algorithm>
void hflip()
for(int row = 0; row < numRows; ++row)
std::reverse(picture[row], picture[row] + numCols);
【讨论】:
以上是关于水平翻转数组?的主要内容,如果未能解决你的问题,请参考以下文章
使用PythonOpenCV翻转图像(水平垂直水平垂直翻转)
利用OpenCV的flip()函数实现图像的水平镜像(水平翻转)垂直镜像(垂直翻转)
Python水平翻转图像(Horizontally flip Image)