OpenCV+ MFC 對影象的讀取、顯示、儲存
一、安裝和配置
安裝opencv,vc6.0配置工程目錄
Include目錄:
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CV\INCLUDE
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CVAUX\INCLUDE
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CXCORE\INCLUDE
E:\PROGRAM FILES\OPENCV\OPENCV1.0\ML\INCLUDE
E:\PROGRAM FILES\OPENCV\OPENCV1.0\OTHERLIBS\HIGHGUI
E:\PROGRAM FILES\OPENCV\OPENCV1.0\OTHERLIBS\CVCAM\INCLUDE
Lbirary目錄:
E:\PROGRAM FILES\OPENCV\OPENCV1.0\LIB
Source目錄:
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CV\SRC
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CVAUX\SRC
E:\PROGRAM FILES\OPENCV\OPENCV1.0\CXCORE\SRC
E:\PROGRAM FILES\OPENCV\OPENCV1.0\ML\SRC
E:\PROGRAM FILES\OPENCV\OPENCV1.0\OTHERLIBS\HIGHGUI
E:\PROGRAM FILES\OPENCV\OPENCV1.0\OTHERLIBS\CVCAM\SRC
建立MFC工程
新增連結庫 cv.lib cvaux.lib cxcore.lib ml.lib highgui.lib cvcam.lib
StdAfx.h中新增
#include <cv.h>
#include <highgui.h>
#include "Processing.h"
注意: 安裝opencv過程中,勾選新增路徑到系統變數。工程建立好之後,若提示缺少dll檔案,就把opencv安裝目錄下的bin資料夾裡面的所有dll複製到系統C盤的windows/ system32 (64位系統為sysWOW64)中去。
二、Doc類操作
1、文件類doc.h
新增成員
IplImage* pImg; // 讀入影象檔案的原始點陣圖
int m_Display; // 影象顯示標記
CString m_filepath; // 影象路徑
過載開啟文件虛擬函式
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
2、文件類doc.cpp
(1) 構造
pImg = NULL;
m_Display = -1; // 初始為-1
m_filepath="";
(2) 析構
if (pImg) cvReleaseImage(&pImg);
(2) 過載開啟文件虛擬函式
在類檢視中,右鍵CxxxDoc名稱,點選“Add VirtuAl Function …”,雙擊左邊列表中“OnOpenDocument”,確定。
BOOL CxxxDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
m_filepath = lpszPathName;
/* 選擇一副臨時影象 */
IplImage* pTempImg=NULL;
pTempImg = cvLoadImage(lpszPathName,-1);
if (!pTempImg)
{
AfxMessageBox("Load Image Error!");
return FALSE;
}
/* 影象儲存在Doc類成員 */
if (pImg)
cvReleaseImage(&pImg);
pImg=cvCreateImage(cvGetSize(pTempImg),pTempImg->depth,pTempImg->nChannels);
cvCopy(pTempImg,pImg); // 複製影象
cvReleaseImage(&pTempImg); // 釋放臨時影象
//pImg=cvCloneImage(pTempImg);//可代替上面三行 (但易造成記憶體洩漏,推薦用cvCopy)
m_Display = 0; // 讀取到影象後為0
return TRUE;
}
三、View類操作
1、檢視類View.h
新增成員變數
IplImage* saveImg; // 備份點陣圖
IplImage* workImg; // 工作點陣圖
// workImg的資訊;
int m_nHeight, m_nWidth, m_nWidthStep, m_nChannels, m_nDepth;
2、檢視類View.cpp
(1) OnDraw()函式處理
void CModificationView::OnDraw(CDC* pDC)
{
CModificationDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if (pDoc->pImg != NULL) // 有磁碟輸入影象
{
if (pDoc->m_Display == 0) // 磁碟中有新影象, 未顯示
{
// 釋放原影象
if (workImg) cvReleaseImage(&workImg);
if (saveImg) cvReleaseImage(&saveImg);
// 重新分配空間
CvSize size= cvGetSize(pDoc->pImg);
int dep = pDoc->pImg->depth;
int chan = pDoc->pImg->nChannels;
workImg= cvCreateImage(size,dep,chan);
saveImg= cvCreateImage(size,dep,chan);
// 拷貝影象
cvCopy(pDoc->pImg,workImg);
cvCopy(pDoc->pImg,saveImg);
m_ImageType = imageType(workImg); //影象型別
pDoc->m_Display = 1; // 顯示標記,置1
}
}
if (workImg) // 重新整理視窗畫面
{
// 影象基本資訊
m_nWidth = workImg->width;
m_nHeight = workImg->height;
m_nWidthStep= workImg->widthStep;
m_nChannels = workImg->nChannels;
m_nDepth = workImg->depth;
// 設定滾動條 -- 需要設定檢視積累為ScrollView,否者刪除下面3行
CSize sizeTotal;
sizeTotal = CSize(workImg->width,workImg->height);
SetScrollSizes(MM_TEXT,sizeTotal);
// 顯示
RECT rect; // 使用CvvImage類繪圖函式的必要引數
rect.top = 0;
rect.left=0;
rect.bottom=m_nHeight;
rect.right=m_nWidth;
HDC hDC = pDC->GetSafeHdc() ; //pDC->m_hDC;this->m_hDc // 獲取輸出物件控制代碼, ::GetDC(m_hWnd)為全域性函式
CvvImage image;
image.CopyOf(workImg,workImg->nChannels);
image.DrawToHDC(hDC, &rect); // image.Show(hDC,0,0,m_nWidth,m_nHeight); // 採用cv繪圖方式,原點在左下角。
image.Destroy();
}
}
(2) 儲存影象
對按鈕“另存為“(ID_FILE_SAVE_AS)新增訊息響應函式
void CModificationView::OnFileSaveAs()
{
// TODO: Add your command handler code here
if (!workImg)
{
MessageBox("Current View has no image!");
return;
}
CString csBMP="BMP Files(*.BMP)|*.BMP|";
CString csJPG="JPG Files(*.JPG)|*.JPG|";
CString csTIF="TIF Files(*.TIF)|*.TIF|";
CString csPNG="PNG Files(*.PNG)|*.PNG|";
CString csDIB="DIB Files(*.DIB)|*.DIB|";
CString csPBM="PBM Files(*.PBM)|*.PBM|";
CString csPGM="PGM Files(*.PGM)|*.PGM|";
CString csPPM="PPM Files(*.PPM)|*.PPM|";
CString csSR ="SR Files(*.SR) |*.SR|";
CString csRAS="RAS Files(*.RAS)|*.RAS||";
CString csFilter=csBMP+csJPG+csTIF+csPNG+csDIB
+csPBM+csPGM+csPPM+csSR+csRAS;
CString name[]={"","bmp","jpg","tif","png","dib",
"pbm","pgm","ppm","sr", "ras",""};
CString strFileName;
CString strExtension;
CFileDialog FileDlg(false,NULL,NULL,OFN_HIDEREADONLY,csFilter);
// 檔案存檔對話方塊
if (FileDlg.DoModal()==IDOK ) // 輸入了檔名
{
strFileName = FileDlg.m_ofn.lpstrFile;
if (FileDlg.m_ofn.nFileExtension == 0) // 無檔案字尾
{
strExtension = name[FileDlg.m_ofn.nFilterIndex];
strFileName = strFileName + '.' + strExtension;
// 加檔案字尾
}
cvSaveImage(strFileName,workImg); // 當前畫面存檔
}
}