在上篇文章中,咱们介绍了如何用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);并且,在个人电脑上经过试验,经过这种方法进行操做,所花时间也变少了。