1.在vs下创建一个基于对话框的MFC程序。
布局如下图
2.进行初始化
在C***Dlg类中的OnInitDialog()函数中添加如下代码
CWnd *pWnd1 = GetDlgItem(IDC_PIC1); //获取显示摄像头画面的窗口类(参数为控件ID)
CWnd *pWnd2 = GetDlgItem(IDC_PIC2); //获取显示直方图的窗口类
pWnd1->GetClientRect(&rect1); //GetClientRect为获得控件自身的坐标大小
pWnd2->GetClientRect(&rect2);
namedWindow("gray", WINDOW_AUTOSIZE); //设置灰度图显示的窗口名
namedWindow("src", WINDOW_AUTOSIZE); //设置画面显示窗口名
HWND hWndl = (HWND)cvGetWindowHandle("src"); //hWnd 表示窗口句柄,获取窗口句柄
HWND hWnd2 = (HWND)cvGetWindowHandle("gray");
HWND hParent1 = ::GetParent(hWndl); //GetParent函数获取子窗口的父窗口句柄
HWND hParent2 = ::GetParent(hWnd2);
::SetParent(hWndl,pWnd1->m_hWnd); //设置窗口的父类,也就是将两个窗口与两个控件绑定在一起
::SetParent(hWnd2, pWnd2->m_hWnd);
capture.open(0); //打开默认摄像头
capture >> frame; //获取第一帧
resize(frame, frame, Size(rect1.Width(), rect1.Height())); //调节大小与控件大小一致
::ShowWindow(hParent1, SW_HIDE); //隐藏两窗口的父窗口,如不隐藏,将会显示两个窗口,这个原因有待大神讲解
::ShowWindow(hParent2, SW_HIDE);
imshow("src", frame); //在对话框中显示窗口
cvtColor(frame, frame,COLOR_RGB2GRAY); //转为灰度图
grayHist(frame); //绘制灰度图,并显示
然后对上面的一些变量在类中做出声明,全部为public
static BOOL isClose; //程序是否结束
VideoCapture capture; //视频类
Mat frame, next; //用于显示的帧数
CRect rect1,rect2; //控件大小
int Max; //获取两帧灰度图变化的最大值
void grayHist(Mat src); //灰度图的显示
void frameVar(Mat src,Mat next); //获取两帧灰度图变化的最大值
CString m_diff; //这个变量和static text绑定在一起,用于显示变化的最大值
afx_msg void OnBnClickedButton1(); //按钮的消息
afx_msg void OnClose(); //关闭按钮的消息,用于结束循环
按钮消息的实现 OnBnClickedButton1()
while (!isClose) //isClose用于判断是否结束
{
capture >> next; //获取每一帧
resize(next, next, Size(rect1.Width(), rect1.Height())); //图片缩放为与控件同样大
frameVar(frame, next); //获取两帧图像灰度变化最大的差值
next.copyTo(frame); //frame代表上一帧,next下一帧
m_diff.Format(_T("%d"), Max); //将值输入static text 文本
UpdateData(FALSE); //进行更新,将变量值传入控件
imshow("src", frame); //显示图片至文本
cvtColor(frame, frame, COLOR_RGB2GRAY); //转为灰度图
grayHist(frame); //绘制灰度图,并显示到控件
waitKey(30); //每30ms一帧
}
关闭按钮消息的实现 OnClose()
isClose=TRUE; //结束循环
灰度直方图的绘制 grayHist(Mat src)
int arryNum = 1;
const int channels[] = { 0 };
int dims = 1;
const int histSize = 256;
float hranges[] = { 0,256 };
const float *ranges[] = { hranges };
Mat dstHist;
calcHist(&src, arryNum, channels, Mat(), dstHist, dims, &histSize, ranges);
double maxValue = 0;
minMaxLoc(dstHist, NULL, &maxValue, 0, 0);
Mat dstImage(Size(histSize+10, histSize), CV_8UC1, Scalar(255));
for (int i = 0; i < histSize; ++i)
{
int realValue = saturate_cast<int>(dstHist.at<float>(i, 0)*0.9*histSize / maxValue);
line(dstImage, Point(i * 1+5, histSize - 10), Point(i * 1+5, histSize - 10 - realValue), Scalar(88, 100, 52), 1, 4);
}
resize(dstImage, dstImage, Size(rect2.Width(), rect2.Height()));
imshow("gray", dstImage);
求差值frameVar(Mat src,Mat next) Max = 0;
Mat diff = Mat(src.rows, src.cols, CV_8UC1);
int width = src.cols;
int height = src.rows;
for (int i = 0; i < height; ++i)
{
uchar *data1 = src.ptr<uchar>(i);
uchar *data2 = next.ptr<uchar>(i);
uchar *data3 = diff.ptr<uchar>(i);
for (int j = 0; j < width; ++j)
{
data3[j] = fabs(data1[j] -data2[j]);
}
}
for (int i = 0; i < height; ++i)
{
uchar *data = diff.ptr<uchar>(i);
for (int j = 0; j < width; ++j)
{
if ((int)data[j] > Max)
Max = data[j];
}
}