The Core Functionality6(Adding (Changing the contrast and brightness of an image! ))

Goal

  • Initialize a matrix with zeros(零初始化矩阵))
  • Access pixel values (获取像素)
  • Learn what cv::saturate_cast does and why it is useful(使用saturate_cast避免超出范围)
  • Get some cool info about pixel transformations(像素变换?)
  • Improve the brightness of an image on a practical example(提高图片的亮度)

Theory

来源于《计算机视觉:算法以及应用》

Image Processing

  • 通常是一个或者几个图像产生几个图像
  • 图像变换:
    • 点运算
    • 邻域运算

Brightness and contrast adjustments

 f(x):source image pixel,g(x):destination image pixel: 公式如下:很容易理解,不过多解释

g(i,j)=αf(i,j)+β


Code 

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
// we're NOT "using namespace std;" here, to avoid collisions between the beta variable and std::beta in c++17
using std::cin;
using std::cout;
using std::endl;
using namespace cv;
int main( int argc, char** argv )
{
    double alpha = 1.0; /*< Simple contrast control */ //gain
    int beta = 0;        /*< Simple brightness control */  //bias
    String imageName("lena.jpg"); // by default
    if (argc > 1)
    {
        imageName = argv[1];
    }
    Mat image = imread( imageName );
    Mat new_image = Mat::zeros( image.size(), image.type() ); //零初始化
    cout << " Basic Linear Transforms " << endl;
    cout << "-------------------------" << endl;
    cout << "* Enter the alpha value [1.0-3.0]: "; 
    //cin >> alpha;
    alpha = 2.2;
    cout << "* Enter the beta value [0-100]: ";    
    //cin >> beta;
    beta = 50;
    //遍历所有的像素
    for( int y = 0; y < image.rows; y++ ) {
        for( int x = 0; x < image.cols; x++ ) {
            for( int c = 0; c < 3; c++ ) {
                new_image.at<Vec3b>(y,x)[c] =
                  saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta ); //避免超过范围
            }
        }
    }
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    namedWindow("New Image", WINDOW_AUTOSIZE);
    imshow("Original Image", image);
    imshow("New Image", new_image);
    waitKey();
    return 0;

}

代码没有什么好解释的,挺简单的!

CMakeLists.txt文件

    cmake_minimum_required(VERSION 2.8)
    set(CMAKE_CXX_FLAGS "-std=c++11")
    set(VMAKE_BUILD_TYPE "Debug")    
    project( DisplayImage )
    find_package( OpenCV REQUIRED )
    include_directories( ${OpenCV_INCLUDE_DIRS} )
    add_executable( DisplayImage main.cpp )
    target_link_libraries( DisplayImage ${OpenCV_LIBS} )

    install(TARGETS DisplayImage RUNTIME DESTINATION bin)

测试结果如下:


Brightness and contrast adjustments

bias可以提高图片的亮度,但同时由于对比度的降低,图片会略模糊(veil),这时候使用gain>=1解决(deminue)这个问题,也会损失一部分原图像的信息。

Gamma correction

gamma correction是一个非线性变换,会让黑色区域更亮,而较亮区域相对变黑。公式如下和图如下:

O=(I255)γ×255

                

When γ<1, the original dark regions will be brighter and the histogram will be shifted to the right whereas it will be the opposite with γ>1.

Code 

#include <iostream>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
// we're NOT "using namespace std;" here, to avoid collisions between the beta variable and std::beta in c++17
using namespace cv;

namespace
{
/** Global Variables */
int alpha = 100;
int beta = 100;
int gamma_cor = 100;
Mat img_original, img_corrected, img_gamma_corrected;


void basicLinearTransform(const Mat &img, const double alpha_, const int beta_)
{
    Mat res;
    img.convertTo(res, -1, alpha_, beta_); //res = alpha*img+bata,其中-1表示尺寸相同
    hconcat(img, res, img_corrected);
}

void gammaCorrection(const Mat &img, const double gamma_)
{
    CV_Assert(gamma_ >= 0);
    //![changing-contrast-brightness-gamma-correction]
    Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.ptr();
    for( int i = 0; i < 256; ++i)
        p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma_) * 255.0); //gamma transform table

    Mat res = img.clone();
    LUT(img, lookUpTable, res);
    //![changing-contrast-brightness-gamma-correction]
    hconcat(img, res, img_gamma_corrected);
}

void on_linear_transform_alpha_trackbar(int, void *)
{
    double alpha_value = alpha / 100.0;
    int beta_value = beta - 100;
    basicLinearTransform(img_original, alpha_value, beta_value);
}

void on_linear_transform_beta_trackbar(int, void *)
{
    double alpha_value = alpha / 100.0;
    int beta_value = beta - 100;
    basicLinearTransform(img_original, alpha_value, beta_value);
}

void on_gamma_correction_trackbar(int, void *)
{
    double gamma_value = gamma_cor / 100.0;
    gammaCorrection(img_original, gamma_value);
}
}

int main( int argc, char** argv )
{

    String imageName("lena.jpg"); // by default,读取图片
    if (argc > 1)
    {
        imageName = argv[1];
    }

    img_original = imread( imageName );
    img_corrected = Mat(img_original.rows, img_original.cols*2, img_original.type()); //两个矩阵,需要容纳两个图片
    img_gamma_corrected = Mat(img_original.rows, img_original.cols*2, img_original.type());

    hconcat(img_original, img_original, img_corrected); //第一和第二个生成第三个
    hconcat(img_original, img_original, img_gamma_corrected); //地一个和第二个生成第三个

    namedWindow("Brightness and contrast adjustments", WINDOW_AUTOSIZE);
    namedWindow("Gamma correction", WINDOW_AUTOSIZE);

    createTrackbar("Alpha gain (contrast)", "Brightness and contrast adjustments", &alpha, 500, on_linear_transform_alpha_trackbar);
    createTrackbar("Beta bias (brightness)", "Brightness and contrast adjustments", &beta, 200, on_linear_transform_beta_trackbar);
    createTrackbar("Gamma correction", "Gamma correction", &gamma_cor, 200, on_gamma_correction_trackbar);

    while (true)
    {
        imshow("Brightness and contrast adjustments", img_corrected);
        imshow("Gamma correction", img_gamma_corrected);


        int c = waitKey(30); //ESC:27
        if (c == 27)
            break;
    }

    imwrite("linear_transform_correction.png", img_corrected);
    imwrite("gamma_correction.png", img_gamma_corrected);

    return 0;
}

CMakeLists.txt文件:

    cmake_minimum_required(VERSION 2.8)
    set(CMAKE_CXX_FLAGS "-std=c++11")
    set(VMAKE_BUILD_TYPE "Debug")
    project( DisplayImage )
    find_package( OpenCV REQUIRED )
    include_directories( ${OpenCV_INCLUDE_DIRS} )
    add_executable( DisplayImage main.cpp )

    target_link_libraries( DisplayImage ${OpenCV_LIBS} )

    install(TARGETS DisplayImage RUNTIME DESTINATION bin)

运行结果如下,且表面: 当alpha>=1和bias>=0时,图片亮度增加;当gamma<1时,图片亮度增加!


猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80157785