首页 > 解决方案 > 尝试在 OpenCV 中使用像素值显示图像。只有 1/3 的图像显示

问题描述

我正在尝试读取图像中的像素并通过遍历像素将它们转换为另一种格式。

转换后,我似乎只得到了图像的 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()这里只是一个占位符,所以我只能分享相关的代码。

生成的图像只是图像的前三分之一:

裁剪的摄像头图像,仅显示前 1/3 的垂直条

标签: c++opencvimage-processing

解决方案


您正在使用 加载图像cv::imread,默认值 ( cv::IMREAD_COLOR) 会将其加载为类型CV_8UC3(aka 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);

推荐阅读