MFC 通过opencv打开摄像头 拍照后显示保存

参考其他人的代码,写了个程序,采用opencv 读取摄像头,点击按钮后完成拍照,并保存图片

界面中有两个picture control 控件   一个ID 为IDC_STATIC 用于显示拍照后的图片   另一个ID为IDC_VIDEO用于打开摄像头显示区,另外还放了三个按钮  分别用于打开摄像头、关闭摄像头及拍照

代码如下:

首先在头文件中添加opencv的一些函数

#pragma once
#include "CvvImage.h"
#include "cv.h"
#include <highgui.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

定义函数:

public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
     void DrawPicToHDCC(IplImage *img,UINT ID);
IplImage *image;

在.cpp文件中定义

IplImage outImage;
Mat frame;
IplImage *outvedio=NULL;
VideoCapture cap;

在OnInitDialog()函数中添加:

// TODO: 在此添加额外的初始化代码
cap.set(CV_CAP_PROP_FRAME_WIDTH,64);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,48);

void CMyVoiceDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int x, y;
CvvImage out;
CRect outrect;
if (!cap.isOpened())
{
fprintf(stderr, "Can not open camera.\n");
return;
}
cap >> frame;
outImage = frame;
outvedio = &outImage;
out.CopyOf(outvedio);
x = out.Width();
y = out.Height();
//获取Picture Control控件的大小  
GetDlgItem(IDC_VIDEO)->GetWindowRect(&outrect);
//将客户区选中到控件表示的矩形区域内  
ScreenToClient(&outrect);
//窗口移动到控件表示的区域  
GetDlgItem(IDC_VIDEO)->MoveWindow(outrect.left, outrect.top, x, y, TRUE);
CWnd *ppWnd = NULL;
ppWnd = GetDlgItem(IDC_VIDEO);//获取控件句柄  
ppWnd->GetClientRect(&outrect);//获取句柄指向控件区域的大小  
CDC *ppDc = NULL;
ppDc = ppWnd->GetDC();//获取picture的DC  
out.DrawToHDC(ppDc->m_hDC, outrect);//将图片绘制到picture表示的区域内  
ReleaseDC(ppDc);
CDialogEx::OnTimer(nIDEvent);
}
IplImage drawpic(IplImage *pImgSrc)
{
IplImage  *pImg8u = NULL;  //Define a pic   灰度图
IplImage  *pImg8u_jun = NULL;  //Define a pic   
IplImage  *pImgCanny = NULL;  //Define a pic 边缘检测后的图
IplImage *pImgDst=NULL;//在图像上检测到直线后的图
CvSeq *lines=NULL;
CvMemStorage *storage=NULL;
pImg8u = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);
pImg8u_jun = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);
pImgCanny = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);     //canny算子边缘检测后的图像
cvSmooth(pImgSrc, pImgSrc, CV_GAUSSIAN, 3, 3);   //高斯滤波
cvCvtColor(pImgSrc, pImg8u, CV_RGB2GRAY);
cvEqualizeHist(pImg8u, pImg8u_jun);
//canny算子检测边缘
cvCanny(pImg8u, pImgCanny, 9, 45, 3);
/*return *pImgCanny;*///若返回该句,则为灰度图


/*检测直线*/
storage = cvCreateMemStorage (0);
lines = cvHoughLines2 (pImgCanny, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 200, 10);
pImgDst = cvCreateImage (cvGetSize(pImgSrc), IPL_DEPTH_8U, 3);
cvCvtColor (pImg8u, pImgDst, CV_GRAY2BGR);


/*在pImgDst上画出检测到的直线*/
for (int i = 0; i < lines->total; i++)
{
CvPoint* line = (CvPoint*)cvGetSeqElem (lines, i);
//cvLine (pImgDst, line[0], line[1], CV_RGB(255,0,0), 3, 8);
}
return *pImgDst;



}

//打开摄像头
void CMyVoiceDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
cap.open(0);
SetTimer(1, 100, NULL);
}

//拍照
void CMyVoiceDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
int cx, cy;
CvvImage image;
CRect rect;
    outvedio = &drawpic(outvedio);//若屏蔽该句,则为原始图片,不做任何处理
image.CopyOf(outvedio);
//获取图片的宽 高度  
cx = image.Width();
cy = image.Height();
//获取Picture Control控件的大小  
GetDlgItem(IDC_STATIC)->GetWindowRect(&rect);
//将客户区选中到控件表示的矩形区域内  
ScreenToClient(&rect);
//窗口移动到控件表示的区域  
GetDlgItem(IDC_STATIC)->MoveWindow(rect.left, rect.top, cx, cy, TRUE);
//GetDlgItem(IDC_STATIC)->MoveWindow(rect.left, rect.top, rect.right, rect.left, TRUE);
CWnd *pWnd = NULL;
pWnd = GetDlgItem(IDC_STATIC);//获取控件句柄  
pWnd->GetClientRect(&rect);//获取句柄指向控件区域的大小  
CDC *pDc = NULL;
pDc = pWnd->GetDC();//获取picture的DC  
image.DrawToHDC(pDc->m_hDC, rect);//将图片绘制到picture表示的区域内  

CString str;
const int N=100;
int result=rand()%N;
//str.Format("E://image/%d.jpg",result);
str.Format("photo//%d.jpg",result);
cvSaveImage((LPSTR)(LPCTSTR)str,outvedio,0);//保存图片
ReleaseDC(pDc);
}
//关闭摄像头
void CMyVoiceDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
cap.release();
image=NULL; //原始图像
if(image) cvReleaseImage(&image);
//image = cvLoadImage("nihao.png",1); //显示图片
image = cvLoadImage("background_company.png",1); //显示图片
DrawPicToHDCC(image, IDC_VIDEO);



}
void CMyVoiceDlg::DrawPicToHDCC(IplImage *img,UINT ID)
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf( img ); // 复制图片
cimg.DrawToHDC( hDC, &rect ); // 将图片绘制到显示控件的指定区域内
ReleaseDC( pDC );


}

MFC 是指Microsoft Foundation Class,是一种框架,用于快速开发Windows应用程序。而OpenCV是一种开源计算机视觉库,它提供了各种图像处理和计算机视觉算法的函数和工具。 要在MFC应用程序中链接摄像头,我们可以使用OpenCV库来实现。首先,我们需要在项目中包含OpenCV的头文件和库文件。 然后,我们可以使用OpenCV的函数来初始化和打开摄像头。例如,我们可以使用`cv::VideoCapture`类的构造函数来打开摄像头,如下所示: ```cpp cv::VideoCapture capture(0); // 打开默认摄像头 ``` 在打开摄像头后,我们可以使用`cv::VideoCapture`的`read`函数来读取摄像头的每一帧图像,如下所示: ```cpp cv::Mat frame; // 存储每一帧图像 while (true) { capture.read(frame); // 读取摄像头图像 cv::imshow("摄像头", frame); // 显示图像 if (cv::waitKey(30) >= 0) break; // 等待按键退出 } ``` 在上述代码中,我们使用`cv::imshow`函数将每一帧图像显示在一个窗口中,并使用`cv::waitKey`函数等待按键输入退出循环。 需要注意的是,这只是链接摄像头的基本示例。根据具体需求,我们可以进一步使用OpenCV库提供的其他函数进行图像处理、特征提取等操作,实现更多功能。 总结起来,要在MFC应用程序中链接摄像头,可以使用OpenCV库提供的函数和工具来实现初始化摄像头、读取每一帧图像和进行图像处理等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值