計算番茄葉片面積:灰度變換 → 輪廓提取 → 像素計數。手寫圖像處理類涉及調色板、DIB 操作極其繁瑣。引入 OpenCV 跨平台視覺庫,算法即調用。
cv.lib cvaux.lib highgui.lib cvcam.lib cxcore.lib)void ResizeImage(IplImage* img) {
int w = img->width, h = img->height;
int max = (w > h) ? w : h;
float scale = (float)max / 256.0f;
int nw = cvRound(w / scale), nh = cvRound(h / scale);
int tlx = (nw > nh) ? 0 : (256 - nw) / 2;
int tly = (nw > nh) ? (256 - nh) / 2 : 0;
cvSetImageROI(TheImage, cvRect(tlx, tly, nw, nh));
cvResize(img, TheImage);
cvResetImageROI(TheImage);
}
void ShowImage(IplImage* img, UINT ID) {
CDC* pDC = GetDlgItem(ID)->GetDC();
HDC hDC = pDC->GetSafeHdc();
CRect rect; GetDlgItem(ID)->GetClientRect(&rect);
int tx = (rect.Width() - img->width) / 2;
int ty = (rect.Height() - img->height) / 2;
SetRect(rect, tx, ty, tx + img->width, ty + img->height);
CvvImage cimg; cimg.CopyOf(img);
cimg.DrawToHDC(hDC, &rect);
ReleaseDC(pDC);
}
void OnButtonLoad() {
CFileDialog dlg(TRUE, _T("bmp"), NULL, OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
_T("Image Files (*.bmp;*.jpg)|*.bmp;*.jpg|All Files|*.*||"), NULL);
dlg.m_ofn.lpstrTitle = _T("Open Image");
if (dlg.DoModal() != IDOK) return;
CString path = dlg.GetPathName();
IplImage* ipl = cvLoadImage(path, 1); // 彩色
IplImage* gray = cvLoadImage(path, 0); // 灰度
if (!ipl) return;
cvZero(TheImage); // 清空上一幀
ResizeImage(ipl);
ShowImage(TheImage, IDC_ShowImg);
// 後續算法處理見下篇
}
大津法自適應閾值 → 二值化 → 輪廓檢測 → 面積過濾填充 → 像素計算 → 硬幣參考物標定 → 實際面積換算。