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


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

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

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

這個式子很好理解。就是將原來圖像中的像素值進行比例變換,后又進行了移動。alpha一般叫做增益參數,表征對比度,而beta成為偏置參數,表征亮度變化。

對圖像的每個像素進行操作,其實我們在前面的文章中已經介紹過了,比如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函數的使用。這個函數用來完成一個類型到另一個類型的轉換(當然,這種類型的轉換必須是被允許的)。而如果被轉換的值超過了目的類型的界限時,該函數會自動返回界限值。

比如:


這樣,我們就實現了對圖像對比度和亮度的變換操作:


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

如果參數中的rType為負數,則轉換前后圖像的類型不變,所以,我們可以用一行代碼實現我們原來的操作:

A.convertTo (B,-1,2,0);

而且,在我的電腦上通過試驗,通過這種方法進行操作,所花時間也變少了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM