C++ Opencv:Mat::at只允许修改图像的一部分

C++ Opencv:Mat::at只允许修改图像的一部分,c++,opencv,C++,Opencv,我正在使用opencv 3.2(此库的新版本),并注意到cv::Mat::at方法的一些奇怪行为 首先,键入myMat.at时,有关方法签名的帮助说明不会显示在QTcreator中,但会显示在其余方法中 第二,当迭代图像像素时,它只修改图像的一部分(我最好显示一个屏幕截图和代码) 代码 #include <QCoreApplication> #include <QDebug> #include <opencv2/opencv.hpp> #include &

我正在使用opencv 3.2(此库的新版本),并注意到
cv::Mat::at
方法的一些奇怪行为

首先,键入
myMat.at
时,有关方法签名的帮助说明不会显示在QTcreator中,但会显示在其余方法中

第二,当迭代图像像素时,它只修改图像的一部分(我最好显示一个屏幕截图和代码)

代码

#include <QCoreApplication>
#include <QDebug>

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <stdint.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    cv::Mat orignalImg = cv::imread("/path/to/image/pic3.jpg", cv::IMREAD_ANYCOLOR);
    cv::Mat modifiedImg = cv::imread("/path/to/image/pic3.jpg", cv::IMREAD_ANYCOLOR);

    for (int r = 0; r < modifiedImg.rows; ++r)
    {
        for (int c = 0; c < modifiedImg.cols; ++c)
        {
            modifiedImg.at<uint8_t>(r, c) = modifiedImg.at<uint8_t>(r, c) * 0.2f;
        }
    }

    cv::imshow("original", orignalImg);
    cv::imshow("modified", modifiedImg);
    cv::waitKey(0);
    return a.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
qcorea应用程序(argc、argv);
cv::Mat orignalImg=cv::imread(“/path/to/image/pic3.jpg”,cv::imread\u ANYCOLOR);
cv::Mat modifiedImg=cv::imread(“/path/to/image/pic3.jpg”,cv::imread\u ANYCOLOR);
对于(int r=0;r
正如你所看到的,右边的图像没有被完全处理,但只是部分处理

为什么会这样? 根据代码,它应该处理整个图像


我遗漏了什么?

您正在使用
at
访问
Mat
(顺便说一句,您应该使用
at
),这意味着图像的类型为
CV_8UC1
,即1个通道(
C1
)的矩阵,其基础类型为8位无符号(
8U

但是,您的图像是彩色图像,这意味着它有3个通道(
C3
),类型为8位无符号(
8U
),这意味着8位用于表示每种颜色B、G、R(
0:255
)。这意味着图像的类型为
CV_8UC3
,您应该在
处使用
访问它

因此,您的代码变成:

 modifiedImg.at<Vec3b>(r, c) = modifiedImg.at<Vec3b>(r, c) * 0.2f; 


您还可以将
imread
cv::imread\u COLOR
(默认值)一起使用,以确保加载带有3个通道的图像。

您使用的
cv::Mat::at
不正确。您有彩色图像(即3通道图像),但您在
处有
而不是
处有
。@DanMašek为什么不正确??3通道表示rgb颜色模型,每个通道都需要无符号字符(0,255),不是吗?当然,但在访问这些值时,您没有指定通道,只指定行和列。是的,我在使用vec3b之前尝试过,它工作正常,但使用uchar它仍然输出相同的错误。这不是错误,只是做错了。使用CV_8UC3矩阵的正确方法是使用Vec3b。很高兴它有帮助;)但在正常工作的windows机器上,我的意思是当使用uint8时,它会填充整个图像,因为您可能正在加载灰度(1通道)图像。您可以使用_映像检查频道数。channels()
modifiedImg = modifiedImg * 0.2f;