基本的灰度变换
最近在学习数字图像处理,更新一些基础知识,并使用opencv和C++做复现。
基本的灰度变化就是对图像像素点做运算,使其满足我们的需求。
几种基本的灰度变换,像素点对应情况如下图所示:
1、图像反转
若原图像灰度量级【0-L-1】,则现图像每个像素点灰度为x,变化后为L-1-X。总体变换效果就是暗的变亮,量的变暗。
1 void reverse(Mat src1) 2 { 3 Mat src(src1.size(), CV_8UC1); 4 cvtColor(src1, src, CV_RGB2GRAY); 5 Mat deimage(src.size(), CV_8UC1); 6 int IMGH = src.rows; 7 int IMGW = src.cols; 8 uchar* p = src.data; 9 uchar* pd = deimage.data; 10 int step = src.step; 11 for (int i = 0; i < IMGH; i++) 12 { 13 for (int j = 0; j < IMGW; j++) 14 { 15 pd[i*step + j] = 255 - p[i*step + j]; 16 } 17 } 18 imshow("原图", src); 19 imwrite("原图.jpg", src); 20 imwrite("变换后图.jpg", deimage); 21 imshow("变换后图", deimage); 22 waitKey(0); 23 }
效果展示:
2、对数变换
即将像素值变为对数形式。由于对数函数的特点,该变换将较暗区域的像素值映射到较量区域,增加整体图像亮度。
1 void logtrans(Mat src) 2 { 3 float hist[256]; 4 for (int i = 0; i < 256; i++) 5 { 6 hist[i] = log(1+i); 7 } 8 Mat graysrc; 9 cvtColor(src, graysrc, CV_RGB2GRAY); 10 Mat yimage(graysrc.size(), CV_32FC1); 11 for (int i = 0; i < src.rows; i++) 12 { 13 for (int j = 0; j < src.cols; j++) 14 { 15 yimage.at<float>(i, j) = hist[graysrc.at<uchar>(i, j)]; 16 } 17 } 18 Mat dst(graysrc.size(), CV_8UC1); 19 normalize(yimage, dst, 0, 255, NORM_MINMAX); 20 convertScaleAbs(dst,dst); 21 imshow("对数变换", dst); 22 imwrite("对数变换.jpg", dst); 23 waitKey(0); 24 25 }
效果展示:
3、幂律变换
和对数变换相似,将像素变换为指数形式,公式为cry。不同的是可通过控制参数决定扩大较暗区域或较量区域的大小。像素变换前后值如下图:
代码略过。参照对数变换,y为5
4、分段变换与灰度分层
分段变换即将不同段的像素进行不同的像素变换。 灰度分层只每一层灰度表示不同的信息。
代码略过参照前面图,结果如下:
灰度分层即找到某阈值,不同灰度面代表不同的图像信息。大于阈值的设为255,小于阈值设为0,即可看出细节信息。这点到阈值分割的时候再讲。