一张图像来说,会有不同的亮暗程度,很多时候都要增强一下,增强的方法有很多,从大量可以说是线性变换和非线性变换,当然这是说空间域的,频率域的暂时不考虑。
线性变换增强,也是对点的操作,如下图
一、点操作,线性增强
<span style="font-size:18px;">#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
double alpha; /**< 控制对比度 */
int beta; /**< 控制亮度 */
int main( int argc, char** argv )
{
/// 读入用户提供的图像
Mat image = imread("lena.jpg" );
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;
//cout << "* Enter the beta value [0-100]: ";
//cin >> beta;
int alpha=2;
int beta=20;
/// for循环执行运算 new_image(i,j) = alpha*image(i,j) + beta
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", 1);
namedWindow("New Image", 1);
/// 显示图像
imshow("Original Image", image);
imshow("New Image", new_image);
/// 等待用户按键
waitKey();
return 0;
}</span>
二、带滑动条的图像对比度增强
<span style="font-size:18px;">C++: int createTrackbar(conststring& trackbarname, conststring& winname,
int* value, int count, TrackbarCallback onChange=0,void* userdata=0); </span>
- 第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
- 第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
- 第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
- 第四个参数,int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
- 第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
- 第六个参数,void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
<span style="font-size:18px;">
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
static void ContrastAndBright(int, void *);
int g_nContrastValue; //对比度值
int g_nBrightValue; //亮度值
Mat g_srcImage,g_dstImage;
int main( )
{
g_srcImage = imread( "lena.jpg");
g_dstImage = Mat::zeros( g_srcImage.size(), g_srcImage.type() );
g_nContrastValue=80;
g_nBrightValue=80;
namedWindow("【效果图窗口】", 1);
//创建轨迹条
createTrackbar("对比度:", "【效果图窗口】",&g_nContrastValue, 300,ContrastAndBright );
createTrackbar("亮 度:", "【效果图窗口】",&g_nBrightValue, 200,ContrastAndBright );
//调用回调函数
ContrastAndBright(g_nContrastValue,0);
ContrastAndBright(g_nBrightValue,0);
//输出一些帮助信息
cout<<endl<<"\t运行成功,请调整滚动条观察图像效果\n\n"
<<"\t按下“q”键时,程序退出\n";
//按下“q”键时,程序退出
while(char(waitKey(1)) != 'q') {}
return 0;
}
static void ContrastAndBright(int, void *)
{
namedWindow("【原始图窗口】", 1);
// 三个for循环,执行运算 g_dstImage(i,j) = a*g_srcImage(i,j) + b
for( int y = 0; y < g_srcImage.rows; y++ )
{
for( int x = 0; x < g_srcImage.cols; x++ )
{
for( int c = 0; c < 3; c++ )
{
g_dstImage.at<Vec3b>(y,x)[c] = saturate_cast<uchar>( (g_nContrastValue*0.01)*( g_srcImage.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
}
}
}
// 显示图像
imshow("【原始图窗口】", g_srcImage);
imshow("【效果图窗口】", g_dstImage);
}
</span>
三、Matlab辅助
maltab中主要用的函数是imadjust()
<span style="font-size:18px;">J = imadjust(I,[low_in high_in],[low_out high_out])</span>
- [low_in high_in]为原图象中要变换的灰度范围,
- [low_out high_out]指定了变换后的灰度范围。
clear all;
I = imread('pout.tif');
J = imadjust(I);
subplot(1,4,1);imshow(I),
xlabel('(a)原始图像')
subplot(1,4,2), imshow(J)
xlabel('(b)增强对比度所得图像')
K=imadjust(I,[0.4,0.8],[]); %对指定的灰度范围进行图像增强处理
subplot(1,4,3), imshow(K)
xlabel('(c)指定对比度范围增强图像')
K1=imadjust(I,[],[0.4 0.6]); %对指定的灰度范围进行图像增强处理
subplot(1,4,4), imshow(K1)
xlabel('(d)指定对比度范围增强图像')
K2=imadjust(I,[0.5 0.8],[],0.5); %对指定的灰度范围进行图像增强处理
figure
imshow(K2)