由於項目需求.md

由於項目需求,採用MFC實現手持血管增強。工具平臺已經發生了較大變化,對GOMfcetemplate進行重構;
根據現有理解,首先嚐試64位平臺。
1、生成MFC dialog

2、引入OpenCV,顯示圖片
還是區分3個地方,分別是 目錄,解決include

鏈接器,解決lib

以及Dll,同步引入GOCVHelper,目前最新2020版本

測試圖片顯示:

進一步測試MFC控件自己的圖片顯示(現在已經可以不使用CVVImage了)

這裏對代碼進行一些修改,方便調用。
// 在指定控件中顯示圖片
void CMFCApplicationDlg::showImage(Mat src, UINT ID)
{
if (src.empty())
return;
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect); // 獲取顯示控件(位置)的 HDC(設備句柄)
CDC* pDC = GetDlgItem(ID)->GetDC();
HDC hDC = pDC->GetSafeHdc();
BITMAPINFO bmi = { 0 }; //生成bitmap信息
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biWidth = src.cols;
bmi.bmiHeader.biHeight = src.rows * -1;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;

RGBTRIPLE* m_bitmapBits = new RGBTRIPLE[src.cols * src.rows];  //拷貝到內存中
Mat cv_bitmapBits(Size(src.cols, src.rows), CV_8UC3, m_bitmapBits);
src.copyTo(cv_bitmapBits);                     
if (rect.Width() > src.cols)                 //結果顯示出來
    SetStretchBltMode(hDC,HALFTONE);
else
    SetStretchBltMode(hDC, COLORONCOLOR);
::StretchDIBits(hDC, 0, 0, rect.Width(), rect.Height(), 0, 0, src.cols, src.rows, src.data, &bmi, DIB_RGB_COLORS, SRCCOPY);

delete(m_bitmapBits )
ReleaseDC(pDC);

}

3、引入視頻採集,處理視頻
引入Dshow獲得視頻數據。首先是include

而後是lib

最後總的來說,使用的還是“Video Capture using DirectShow Author: Shiqi Yu ”
按照說明,將CameraDS.h CameraDS.cpp以及目錄DirectShow複製到你的項目中

不要忘記添加CmaeraDS.h

正確設置的話,應該可以直接運行。

在Oninit_dialog中獲得攝像頭變量

m_nCamCount = CCameraDS::CameraCount();//攝像頭總數
//獲得攝像頭數目
char camera_name[1024];
char istr[25];
for (int i = 0; i < m_nCamCount; i++)
{
int retval = CCameraDS::CameraName(i, camera_name, sizeof(camera_name));
sprintf_s(istr, " # %d", i);
strcat_s(camera_name, istr);
CString camstr(camera_name);
if (retval > 0)
m_CBNCamList.AddString(camstr);
else
AfxMessageBox(_T("不能獲取攝像頭的名稱"));
}
這個時候,啓動的時候就可以自動獲得攝像頭。

那麼我們選中並打開採集線程。這裏細節很多,線程函數需要獨立撰寫

//攝像頭顯示循環,所有關於採集的操作是通過主線程傳遞控制變量到採集線程,而後由採集線程完成的
DWORD WINAPI CaptureThread(LPVOID lpParameter)
{
CGOMfcTemplate2Dlg* pDlg = (CGOMfcTemplate2Dlg)lpParameter;
double t_start = (double)cv::getTickCount(); //開始時間
Mat tmpPrydown;
//#pragma omp parallel for
while (true)
{
if (pDlg->b_closeCam)//退出循環
break;
double t = ((double)cv::getTickCount() - t_start) / getTickFrequency();
if (t <= 0.1)//fps =10,主動降低速度
{
Sleep(100);
continue;
}
else
{
t_start = (double)cv::getTickCount();
}
//從directX中獲得當前圖像並顯示出來
IplImage
queryframe = pDlg->cameraDs.QueryFrame();
//在2.0版本中可以強轉,在3.0中需要使用函數
Mat camframe = cvarrToMat(queryframe);
pDlg->showImage(camframe, IDC_CAM); //顯示原始圖像
////根據條件,決定是否採用算法
Mat dst;
Mat img;
cvtColor(camframe, img, COLOR_BGR2GRAY);
cvtColor(img, img, COLOR_GRAY2BGR);
if (pDlg->bMethod) //這裏實現的是灰度轉彩色
{
// extract L channel and subtract mean
Mat lab, L, input;
img.convertTo(img, CV_32F, 1.0 / 255);
cvtColor(img, lab, COLOR_BGR2Lab);
extractChannel(lab, L, 0);
resize(L, input, Size(W_in, H_in));
input -= 50;
// run the L channel through the network
Mat inputBlob = blobFromImage(input);
pDlg->net.setInput(inputBlob);
Mat result = pDlg->net.forward();
// retrieve the calculated a,b channels from the network output
Size siz(result.size[2], result.size[3]);
Mat a = Mat(siz, CV_32F, result.ptr(0, 0));
Mat b = Mat(siz, CV_32F, result.ptr(0, 1));
resize(a, a, img.size());
resize(b, b, img.size());
// merge, and convert back to BGR
Mat color, chn[] = { L, a, b };
merge(chn, 3, lab);
cvtColor(lab, dst, COLOR_Lab2BGR);
dst.convertTo(dst, CV_8UC3, 255); //保證輸入到imageshow中的是8u rgb
}
else
{
dst = img.clone();
}
pDlg->showImage(dst, IDC_PIC); //顯示網絡處理圖像
}
return 0;
}

這時就顯示出來啦。基礎的顯示、採集工作就完畢了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章