學習OpenCV(四) 改變圖像的對比度和亮度——像素變換

在上篇文章中,咱們介紹瞭如何用filter2D函數來對圖像進行鄰域變換。這篇文章咱們來簡單介紹一下如何對圖像的像素進行變換。ios

對圖像的單個像素進行變換,是圖像處理中一個很常見的操做。好比改變圖像的亮度,對圖像像素進行線性變換,二值化等。下面將以改變圖像的對比度和亮度來舉例。函數

改變圖像的對比度和亮度,歸根到底,就是下面的這個數學公式:ui

這個式子很好理解。就是將原來圖像中的像素值進行比例變換,後又進行了移動。alpha通常叫作增益參數,表徵對比度,而beta成爲偏置參數,表徵亮度變化。spa

對圖像的每一個像素進行操做,其實咱們在前面的文章中已經介紹過了,好比LUT查表操做,直接用指針訪問,或是用迭代器等。下面的這段代碼實現了對圖像對比度和亮度的這一操做,咱們用指針實現:指針

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv/cv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat ChangePixel(const Mat& img,const double alpha,const int beta)
{
	Mat newImg=Mat::zeros(img.size(),img.type ());    // the img to be returned
	int chnnels=img.channels ();            //Get the channels of source img
	for (int x=0;x<img.rows;x++)             //iteration rows
	{
		//用指針訪問
		const uchar *p=img.ptr <uchar>(x);    //因爲img被聲明爲const,因此指針也要聲明爲const
		uchar *q=newImg.ptr <uchar>(x);
		int cols=img.cols*chnnels;
		for (int y=0;y<cols;y++)
		{
			q[y]=saturate_cast<uchar>(p[y]*alpha+beta);  //注意saturate_cast的使用
		}
		
	}
	return newImg;
}

int main()
{
	int64 time_start=getTickCount ();
	Mat A=imread ("lena.jpg",CV_LOAD_IMAGE_COLOR);
	imshow ("A的圖像",A);

	Mat B=ChangePixel (A,2,0);
	imshow ("B的圖像",B);
	int64 time_end=getTickCount ();
	double time_take=(time_end-time_start)*1000.0/getTickFrequency ();
	cout<<"The time is "<<time_take<<"ms"<<endl;
	waitKey ();
	return 0;
}

注意代碼中saturate_cast函數的使用。這個函數用來完成一個類型到另外一個類型的轉換(固然,這種類型的轉換必須是被容許的)。而若是被轉換的值超過了目的類型的界限時,該函數會自動返回界限值。code

好比:
get


這樣,咱們就實現了對圖像對比度和亮度的變換操做:數學


不過,OpenCV中已經有了進行這樣處理的函數:Mat::convertTo,它能夠完成圖像的數據類型轉換,同時,對像素值進行改變。it

若是參數中的rType爲負數,則轉換先後圖像的類型不變,因此,咱們能夠用一行代碼實現咱們原來的操做:io

A.convertTo (B,-1,2,0);
並且,在個人電腦上經過試驗,經過這種方法進行操做,所花時間也變少了。
相關文章
相關標籤/搜索