您的位置:首页 > 运维架构

opencv调整图像亮度与对比度

2016-12-08 10:17 471 查看
    图像变换的操作一般可以分为下面两种:

    1.基于邻域操作进行区域变换,比如卷积操作、特征提取、图像梯度计算、角点检测、图像模糊与蜕化等。

    2.基于点操作进行像素的变换,比如图像亮度于对比度的调整。

    下面我们对图像的亮度与对比度的调节进行讨论。

    亮度与对比度的调节主要基于下面的公式,其中g(i,j)为处理前的图像,f(i,j)为处理后的图像:

    g(i,j) = alpha * f(i,j) + beta,其中alpha>0,beta是增益变量。

    这个公式是一个线性的变换,通过调整alpha和beta的值就会得到不同的效果。基本原理是这样的,图像f(i,j)乘以一个大于1的alpha值的时候,图像f(i,j)中的像素值之间的差异就会变大,因此对比度就会增强,如果alpha值在0~1之间对比度就会减小。后面的beta是一个增益变量,如果beta取正数的话,图像亮度就会变大,取负数的话图像亮度就会减小。(基本原理就是一次线性函数y=kx+b,调整k和b,y值就会随之变化)

    下面是基于opencv的示例代码:

#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

int main()

{
    Mat src, dst;

    src = imread("1.jpg");
    if(!src.data)
    {

        cout << "could not load image ..." << endl;
    }

    char input_win[] = "input image";
    namedWindow(input_win, CV_WINDOW_AUTOSIZE);
    imshow(input_win, src);

    //contrast and brightness changes
    int height = src.rows;
    int width = src.cols;

    dst = Mat::zeros(src.size(), src.type());

    float alpha = 1.2;
    float beta  = 30;

    for(int row = 0; row < height; row++)
    {
        for(int col = 0; col < width; col++)
        {
            if(src.channels() == 3)
            {
                float b = src.at<Vec3b>(row, col)[0]; //blue
                float g = src.at<Vec3b>(row, col)[1]; //green
                float r = src.at<Vec3b>(row, col)[2]; //red

                dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
    }
    else if(src.channels() == 1)
    {
        float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v*beta + beta);
    }
        }
    }

    char output_title[] = "contrast and brightness changes demo";
    namedWindow(output_title, CV_WINDOW_AUTOSIZE);
    imshow(output_title, dst);

    waitKey(0);

    return 0;

}

    上面的代码主要用到opencv函数下面对此进行说明:

    Mat new_image = Mat::zero(image.size(), image.type);//创建一张跟原图大小和类型一致的空白图像、像素初始为0。
    saturate_cast<uchar>(value);//确保值大小为0~255。
    Mat.at<Vec3b>(y,x)[index] = value; //给每个像素点每个通道赋值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: