我试图读取图像中的像素,并通过遍历像素将其转换为另一种格式。
在转换之后,我似乎只得到了图像的1/3,我确信这是因为我使用.at()函数访问像素的方式。
我在下面的图片中看到:
Mat image = imread("cameraman.jpg");
然后,我遍历图像、行和列:
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
placeGrayValue((double)image.at<uchar>(i, j));
}
}
注意:placedGrayValue()
只是这里的占位符,所以我只能共享相关的代码。
生成的图像仅占图像的前三分之一:
发布于 2021-06-04 01:50:34
您正在使用cv::imread
加载映像,默认值(cv::IMREAD_COLOR
)将作为CV_8UC3
(又名cv::Mat3b
)类型的3通道映像加载它。
如果原始图像是灰度图像,当加载为3通道图像时,每个通道的强度值相同。
因此,当您扫描图像时,您应该使用.at<cv::Vec3b>(...)
访问像素。如果您只想将第一个通道复制到placeGrayValue
矩阵,您应该这样做:
placeGrayValue((double)image.at<cv::Vec3b>(i, j)[0]);
^^^^^^^^^ ^^^
3 channel first channel
如果您的输入不是灰度图像,那么您不应该只复制第一个通道,因为灰度值是三个R、G、B通道的线性组合。因此,最好先转换为灰度,然后复制:
cv::Mat grayscale;
cv::cvtColor(image, grayscale, cv::COLOR_BGR2GRAY);
...
placeGrayValue((double)grayscale.at<uchar>(i, j));
^^^^^
1 channel
或者您可以将图像加载为灰度图像:
Mat grayscale = imread("cameraman.jpg", cv::IMREAD_GRAYSCALE);
最后,您希望有一个灰度值为placeGrayValue
的double
。您不应该扫描图像的这种简单的操作。你可以只是:
cv::Mat placeGrayValue;
grayscale.convertTo(placeGrayValue, CV_64F);
^^^^^^
to double type
总结:
cv::Mat grayscale = cv::imread("cameraman.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat placeGrayValue;
grayscale.convertTo(placeGrayValue, CV_64F);
发布于 2021-06-03 05:57:34
我会贴出最后作为答案的文章,尽管这对我来说没有什么意义,我仍然很想知道为什么。
该图像有3个通道。当使用for循环迭代图像并使用(double)image.at<uchar>(i, j)
提取像素数据时,它会遍历每个通道,就好像它们是单个像素一样。
解决方案(至少这个灰度图像)是迭代并乘以3。换句话说,(double)image.at<uchar>(i*3, j)
最终给了我完整的图像。
https://stackoverflow.com/questions/67815919
复制相似问题