用c++改变图像亮度

won*_*cho 0 c++ opencv image-processing brightness computer-vision

我想改变图像的亮度,只访问像素值。不使用opencv函数(例如convertTo)

输入:图像,数字

num 表示亮度常数值

这是我的代码,结果看起来很奇怪。有什么问题吗?

原来的

结果

cv::Mat function(cv::Mat img, int num){
    cv::Mat output;
    output = cv::Mat::zeros(img.rows, img.cols, img.type());
    for (int i = 0; i < img.rows; i++)
    {
        for (int j = 0; j < img.cols; j++)
        {
            for (int c = 0; c < img.channels(); c++)
            {
                output.at<cv::Vec3b>(i, j)[c] = img.at<cv::Vec3b>(i, j)[c] + num;
            
                if (output.at<cv::Vec3b>(i, j)[c] > 255){
                    output.at<cv::Vec3b>(i, j)[c] = 255;
                }
                else if (output.at<cv::Vec3b>(i, j)[c] < 0)
                {
                    output.at<cv::Vec3b>(i, j)[c] = 0;
                }

            }
        
        }

    }
    cv::imshow("output", output);
    cv::waitKey(0);
    return img;
}
Run Code Online (Sandbox Code Playgroud)

ber*_*rak 6

不使用opencv函数

这有点愚蠢,因为您的代码已经使用了 opencv 的数据结构。

为了做到这一点,你还重新发明了轮子,尽管是一个稍微方形的轮子......

在分配给输出之前检查是否溢出。

是的,这就是问题所在。正确的方法是:将总和分配给大于uchar 的值,然后检查

else if (output.at<cv::Vec3b>(i, j)[c] < 0)
Run Code Online (Sandbox Code Playgroud)

这永远不会发生,尝试理解为什么


但请注意,您的整个代码(三重循环,天哪!!!)可以重写为简单的:

Mat output = img + Scalar::all(num);
Run Code Online (Sandbox Code Playgroud)

(更快、更安全,而且这也会正确饱和!)