我拍摄了一张图像,我想将图像作为其对应的像素值写入,并且我已经完成了代码并进行了编译,但是问题是,我将这些值存储在txt文件中,然后将这些值复制到了excel表格,我看到的是,我得到的像素值仅适用于图片的一半,即当我将其视为一幅完整的图片时,像素向我展示的是图片的一半或更少,我不知道,但它并不能向我展示完整的图片图片。
救救我。
#include <opencv2/opencv.hpp>
using namespace cv;
#include <fstream>
using namespace std;
int main()
{
Mat colorImage = imread("/home/bmit/display_image/CIRCLE.jpg");
// Open the file in write mode.
ofstream outputFile("name.txt");
// Iterate through pixels.
int r, c;
for (r = 1; colorImage.rows > r ;r++)
{
for (c = 1; colorImage.cols > c ; c++)
{
int pixel = colorImage.at<uchar>(r,c);
outputFile << pixel << '\t';
}
outputFile << endl;
}
// Close the file.
outputFile.close();
return 0;
}
答案 0 :(得分:1)
我认为许多错误加起来造成了这个问题。首先是对于彩色图像,实际上并没有一个“像素值”-有红色,绿色,蓝色(也可能还有Alpha通道)。从这一点开始,我将假设您实际上是要依次获取每个像素的BGR值。
cv :: Mat通常是指向大块连续存储器奇异块的指针的包装器(它并不总是连续的,但通常是连续的)。 Mat.at<typename>()
方法是访问此数据的一种方法,使用类型名来解释它并强制转换所访问的数据。
您遇到的问题是此矩阵中存储的总信息超过uchar的row * cols。矩阵存储着蓝色,绿色和红色uchar的row * cols * 3个三重奏。代码行int pixel = colorImage.at<uchar>(r,c);
根据uchar的大小,图像中的行数以及r&c的值访问此数据序列中的某个点。
例如,当r等于行数而c等于列数时,在内部循环中的某个点,您将调用int pixel = colorImage.at<uchar>(r,c);
。您希望pixel
的值是右下像素的“像素值”,但实际上得到的是一个像素的通道值之一的值,该像素的宽度大约为宽度的三分之一,图像高度的三分之一。
要解决此问题,您有多种选择。我认为您会发现阅读OpenCV网站(this one probably being the most relevant)上的一些教程很有用。但是,如果您用以下代码替换代码中的循环,它应该可以工作,尽管我尚未对其进行测试。
for (r=0;r<colorImage.rows; r++)
{
for (r=0; c<colorImage.cols; c++)
{
Point3_<uchar> pixel = colorImage.at<Point3_<uchar>>(r,c);
outputFile << pixel.x << '\t'<< pixel.y << '\t'<< pixel.z << '\t';
}
outputFile << endl;
}
请注意,这将按照BGR顺序进行,如果您需要RGB,只需交换pixel.x
和pixel.z
的顺序