基於對話方塊的程式。
實現介面:
開啟圖片的訊息響應函數:
void CcountRiceDlg::OnBnClickedOpen(){// TODO: 在此添加控制項通知處理常式代碼TCHAR szFilters[]=_T("BMP Files (*.bmp)|*.png|All Files (*.*)|*.*||");CFileDialog dlg(TRUE,_T("All Files(*.*)"),_T("*.*"),OFN_OVERWRITEPROMPT,szFilters);if (dlg.DoModal()){CStringpath=dlg.GetPathName();int sizeOfString = (path.GetLength() + 1);LPCTSTR lpsz = new TCHAR[sizeOfString];lpsz =(LPCTSTR)path; CRect outputRect;GetDlgItem(IDC_ORIGIN_PIC)->GetWindowRect(&outputRect); //檢索指定的對話方塊中的控制項控制代碼;返回指定視窗的邊框矩形的尺寸if (m_cvImage->Load(lpsz)){m_hasLoadImg=true;m_cvImage->Show(GetDlgItem(IDC_ORIGIN_PIC)->GetDC()->GetSafeHdc(),0,0,outputRect.Width(),outputRect.Height());}}}
圖片處理的訊息響應函數:
void CcountRiceDlg::OnBnClickedProcess(){// TODO: 在此添加控制項通知處理常式代碼if (!m_hasLoadImg){OnBnClickedOpen();}CvvImage* tmp=new CvvImage;CvvImage* backImage=new CvvImage;IplConvKernel* element=cvCreateStructuringElementEx(4,4,1,1,CV_SHAPE_ELLIPSE,0);//形態學結構指標[建立結構元素,4列4行,橢圓形】tmp->CopyOf(*m_cvImage);backImage->CopyOf(*m_cvImage);cvErode(m_cvImage->GetImage(),tmp->GetImage(),element,10);//腐蝕cvDilate(tmp->GetImage(),backImage->GetImage(),element,10);//這裡得到的backImage是背景映像cvSub(m_cvImage->GetImage(),backImage->GetImage(),tmp->GetImage(),0);//用原始映像減去背景映像,tmp是結果映像cvThreshold(tmp->GetImage(),backImage->GetImage(),50,255,CV_THRESH_BINARY);//這裡得到的backImage是二值圖CvMemStorage* stor=cvCreateMemStorage(0);CvSeq * cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);IplImage* dst;dst = cvCreateImage( cvGetSize(backImage->GetImage()), backImage->GetImage()->depth, 1 );cvCvtColor(backImage->GetImage(), dst, CV_BGR2GRAY );//3通道->1通道int numberOfObject=cvFindContours(dst,stor,&cont,sizeof(CvContour),CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));double maxArea=0;double tmpArea=0;CvSeq* maxAreaRice=0;double maxLength=0;double tmpLength=0;CvSeq* maxLengthRice=0;//cvThreshold(dst,dst,0,255,CV_THRESH_BINARY);//在畫輪廓前先把映像變成白色IplImage* dst_contours = cvCreateImage( cvGetSize(dst), dst->depth, dst->nChannels);cvThreshold( dst_contours, dst_contours ,0, 0, CV_THRESH_BINARY ); //在畫輪廓前先把映像變成黑色。 threshold=0,pixel>0,pixel = 0.for (;cont;cont=cont->h_next){tmpArea=fabs(cvContourArea(cont,CV_WHOLE_SEQ));if(tmpArea>maxArea){maxArea=tmpArea;maxAreaRice=cont;}tmpLength=cvArcLength(cont);if (tmpLength>maxLength){maxLength=tmpLength;maxLengthRice=cont;}if (tmpArea>10){cvDrawContours(dst_contours,cont,CV_RGB(0,0,255),CV_RGB(255,0,0),0,1,8,cvPoint(0,0));//在映像上繪製外部和內部輪廓.//【映像,第一個輪廓指標,外輪廓的顏色,內輪廓的顏色,畫輪廓的最大層數(如果是0,只繪製contour),線條寬度,線條類型,按給定值移動所有點的座標 】}}CRect outputRect; GetDlgItem(IDC_PROCESSED_PIC)->GetWindowRect(&outputRect);m_ProcessedImage->CopyOf(dst_contours,1);CRect rect;SetRect( rect, 0, 0, outputRect.Width(),outputRect.Height() ); m_ProcessedImage->DrawToHDC(GetDlgItem(IDC_PROCESSED_PIC)->GetDC()->GetSafeHdc(),&rect);m_result.Format(_T("米粒數目為: %d 個\n米粒最大面積: %f\n米粒最大周長: %f"),numberOfObject,maxArea,maxLength);UpdateData(FALSE);cvReleaseImage(&dst);cvReleaseImage(&dst_contours);cvReleaseMemStorage(&stor);}
退出按鈕的訊息響應,重載了一下 Dialog的 OnCancel 函數:
void CcountRiceDlg::OnBnClickedExit(){// TODO: 在此添加控制項通知處理常式代碼CDialog::OnCancel();}
記得在解構函式裡面釋放圖片哦~
CcountRiceDlg::~CcountRiceDlg(){if (m_cvImage){delete m_cvImage;}if (m_ProcessedImage){delete m_ProcessedImage;}}
在 DoDataExchange 函數裡面, DDX_Text(pDX, IDC_RESULT, m_result);
是將 CString 類型的m_result 將 控制項 IDC_RESULT 關聯起來~然後,就可以在static text 顯示字串了。。。。。
控制項和變數的關聯是在 DoDataExchange 中顯示的 : DDX_Text(pDX, IDC_RESULT, m_result);
方法VC classwizard -- member variables 。vs 中是在控制項上右擊--添加變數~~~是吧
在 OnInitDialog()
中添加~
m_cvImage=new CvvImage;
m_ProcessedImage=new CvvImage;
m_hasLoadImg=false;
在OnPaint() 的
else 中添加:
CDialog::OnPaint();CRect outputRect;GetDlgItem(IDC_PROCESSED_PIC)->GetWindowRect(&outputRect);m_ProcessedImage->Show(GetDlgItem(IDC_PROCESSED_PIC)->GetDC()->GetSafeHdc(),0,0,outputRect.Width(),outputRect.Height());GetDlgItem(IDC_ORIGIN_PIC)->GetWindowRect(&outputRect);CRect rect;SetRect( rect, 0, 0, outputRect.Width(),outputRect.Height() ); m_cvImage->DrawToHDC(GetDlgItem(IDC_ORIGIN_PIC)->GetDC()->GetSafeHdc(),&rect);
【paint 函數什麼時候被調用呢?當注釋掉 OnBnClickedOpen() 中顯示圖片用的是show函數 時,沒有影響~~~~
WM_PAINT訊息僅用於以下兩種情況:
1. 當使用者移動視窗或顯示視窗,或使用者改變視窗的大小,或滾動視窗使用者區時,Windows會向視窗函數發送WM_PAINT訊息。
2. 當Windows關閉覆蓋視窗部分地區的對話方塊時,以及菜單下拉出來又被釋放時,視窗使用者區被臨時覆蓋,系統會試圖恢複顯示地區,可能向視窗函數發送一條WM_PAINT訊息,要求應用程式重新整理其使用者區。
這兩種情況下將使MFC調用OnPaint處理函數。也僅有這兩種情況,視圖對象具有一個OnPaint處理函數。
開始點擊 [開啟圖片] 時,算是哪種情況呢?%>_<% 】
核心代碼:
int numberOfObject=cvFindContours(dst,stor,&cont,sizeof(CvContour),CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
Area=fabs(cvContourArea(cont,CV_WHOLE_SEQ));
Length=cvArcLength(cont)
圈圈的個數就是 連通地區的個數了
關於LPCTSTR轉換為const
char * ??
如何將LPCTSTR轉換為const
char * ?? 項目--屬性--配置屬性--字元集
改為使用多位元組 居然可以這麼簡單~~~【LPCTSTR
1、在非UNICODE環境下為 const char * 2、在UNICODE環境下為 const unsigned short * so,需要將寬字元轉換為多位元組】
可是,Release版本下,這個還是通不過,網上查了好多,可素,感覺亂七八糟的,誰有簡單又方便的方案????
這個應該自己設計演算法來實現的~~~~~哎~~~菜鳥啊菜鳥,這個才2行核心代碼而已啊,趕緊學著自己寫一個吧%>_<%
具體代碼: http://download.csdn.net/detail/timidsmile/3671517