经过前面的学习,有了对比度,直方图的基础,所以就想着用这滑动条做一个综合的实例,用滑动条去控制直方图,去滑动条控制对比度和亮度,用滑动条控制融合,也是对基础的一点提高,其中还有很多值得改进的,可以动态显示结果之类的,这里就不多介绍。以后有机会再优化。
学习之前,要知道几个函数的使用方法,其他的出现的函数或者用法,请参考前面的基础例子-----------------------链接:Opencv图像识别从零到精通(1)---(11)
一、滑动条的综合示例
int createTrackbar(conststring& trackbarname, conststring& winname,
int* value, int count, TrackbarCallback onChange=0,void* userdata=0);
- 第一个参数,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参数。
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
- 第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
- 第二个参数,alpha,表示第一个数组的权重
- 第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数。
- 第四个参数,beta,表示第二个数组的权重值。
- 第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
- 第六个参数,gamma,一个加到权重总和上的标量值。看下面的式子自然会理解。
- 第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
<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;
#define winname "混合滚动条"
Mat src;
Mat src1;
Mat src2;
Mat src3;
Mat src4;
Mat dst;
Mat dispImg1;
int sidlervalue=10;
int sidlervalue1=10;
const int g_max=100;
const int g_max1=100;
void ontracker(int,void*)
{
double alpha=(double)sidlervalue/g_max;
double beta=(1-alpha);
addWeighted(src1,alpha,src2,beta,0.0,dst);
MatND dstHist;
float hranges[2] = {0, 255};
const float *ranges[1] = {hranges};
int channels = 0;
calcHist(&dst, 1, &channels, Mat(), dstHist, 1, &sidlervalue, ranges);
Mat dstImage(256, 256, CV_8U, Scalar(0));
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist,&minValue, &maxValue, 0, 0);
int hpt = saturate_cast<int>(0.9 * 256);
for(int i = 0; i < sidlervalue; i++)
{
float binValue = dstHist.at<float>(i);
int realValue = saturate_cast<int>(binValue * hpt/maxValue);
line(dstImage,Point(i,256-1),Point((i+1)-1,256-realValue),Scalar(255));
}
namedWindow(winname);
imshow(winname,dst);
namedWindow("一维直方图");
imshow("一维直方图", dstImage);
}
void ontracker2(int,void*)
{
for(int i=0;i<src.rows;i++)
{
for(int j=0;j<src.cols;j++)
{
dst.at<uchar>(i,j)=saturate_cast<uchar>(sidlervalue1+dst.at<uchar>(i,j));
}
}
MatND dstHist;
float hranges[2] = {0, 255};
const float *ranges[1] = {hranges};
int channels = 0;
calcHist(&dst, 1, &channels, Mat(), dstHist, 1, &sidlervalue1, ranges);
Mat dstImage(256, 256, CV_8U, Scalar(0));
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist,&minValue, &maxValue, 0, 0);
int hpt = saturate_cast<int>(0.9 * 256);
for(int i = 0; i < sidlervalue1; i++)
{
float binValue = dstHist.at<float>(i);
int realValue = saturate_cast<int>(binValue * hpt/maxValue);
line(dstImage,Point(i,256-1),Point((i+1)-1,256-realValue),Scalar(255));
}
namedWindow(winname);
imshow(winname,dst);
namedWindow("一维直方图");
imshow("一维直方图", dstImage);
}
int main()
{
vector<Mat> imgs(2);
imgs[0] = imread("peppers.png");
imgs[1] = imread("pillsetc.png");
src4=imgs[1];
src=imgs[0];
cvtColor(src4,src3,COLOR_BGR2GRAY);
cvtColor(src,src2,COLOR_BGR2GRAY);
src1=src3;
Mat dispImg;
int x, y;
x = imgs[0].cols;
y = imgs[0].rows;
int max;
max = (x > y)? x: y;
int dstsize=max;
dispImg.create(Size(dstsize*(1+1)+100,dstsize), CV_8UC3);
int nImg = (int)imgs.size();
for(int i=0;i<nImg;i++)
{
int m=20+i*max;
int n=20;
Mat imgROI = dispImg(Rect(m, n, (int)x, (int)y));
resize(imgs[i], imgROI, Size((int)x, (int)y));
}
namedWindow("winName");
imshow("winName", dispImg);
sidlervalue=10;
namedWindow(winname);
char barname[50];
sprintf(barname,"融合 %d",g_max);
createTrackbar(barname,winname,&sidlervalue,g_max,ontracker);
ontracker(sidlervalue,0);
sidlervalue1=1;
createTrackbar("对比度",winname,&sidlervalue1,g_max1,ontracker2);
ontracker2(sidlervalue1,0);
waitKey(0);
return 0;
}</span>
结果如下
(1)多图显示
(2)滑动条界面
(3)实时动态显示直方图
二、Matlab辅助
对于matlab的按钮滑块,是GUI里面的内容,这个在前面我写了好几篇,有基础入门,也有图像的进阶链接如下
http://blog.csdn.net/qq_20823641/article/category/6310257
图像识别算法交流 QQ群:145076161,欢迎图像识别与图像算法,共同学习与交流