VS+++opencv++MFC++數米粒【計算聯通地區的個數及聯通地區內像素的個數】

來源:互聯網
上載者:User

基於對話方塊的程式。

實現介面:

開啟圖片的訊息響應函數:

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.