MFC与HALCON混合编程三之滑动条控件_选择阈值—backgroundSeg

162 阅读2分钟

引言

使用MFC联合Halcon,将HDevelop中的演示结果用MFC中对话框的形式显示


一、结果

1.1 Halcon演示结果

原图 在这里插入图片描述 结果 在这里插入图片描述

1.2 MFC演示结果

在这里插入图片描述 在这里插入图片描述


1.3 步骤

第一步,新建MFC对话框工程项目,添加控件如图所示 IDC_STATIC_ORIGINAL_IMG IDC_STATIC_PROCESS_IMAGE IDC_BUTTON_READ_IMG IDC_BUTTON_PROCESS_IMG IDC_SLIDER_THRESHOLD IDC_EDIT_THRESHOLD 在这里插入图片描述 第二步,在添加变量和消息响应事件

第三步,导出halcon中backgroundseg为cpp文件,具体代码见下面

二、Halcon代码

* Determine the connected components of the background of given regions
* 
read_image (Image, 'fabrik')
* Detect edges
sobel_amp (Image, EdgeAmplitude, 'thin_sum_abs', 3)
threshold (EdgeAmplitude, Edges, 5, 255)
background_seg (Edges, BackgroundRegions)
* Fill up holes in regions based on shape feature 'area'
fill_up_shape (BackgroundRegions, RegionFillUp, 'area', 1, 40)
dev_clear_window ()
dev_set_colored (6)
dev_display (RegionFillUp)

三、MFC源代码

1.头文件主要代码

public:
	HTuple picture1_WindowID,picture2_WindowID;  //两个picture窗口句柄
	CWnd *pWnd;
	// Local iconic variables
	HObject  ho_Image, ho_EdgeAmplitude, ho_Edges;
	HObject  ho_BackgroundRegions, ho_RegionFillUp;
	HTuple hv_WindowID, hv_Width, hv_Height;
	HObject ho_ConnectedRegions;

public:
	int m_threshold;    //设置阈值法的阈值
	BOOL m_IsEmpty;     //判断是否已经加载图像
	CSliderCtrl m_ctrlSlider;
	afx_msg void OnBnClickedButtonReadImg();
	afx_msg void OnBnClickedButtonProcessImg();
	afx_msg void OnNMCustomdrawSliderThreshold(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnEnChangeEditThreshold();

2.源文件主要代码


//消息映射和数据绑定
//.....
void CHalconMFCDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SLIDER_THRESHOLD, m_ctrlSlider);
}

BEGIN_MESSAGE_MAP(CHalconMFCDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_READ_IMG, &CHalconMFCDlg::OnBnClickedButtonReadImg)
	ON_BN_CLICKED(IDC_BUTTON_PROCESS_IMG, &CHalconMFCDlg::OnBnClickedButtonProcessImg)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_THRESHOLD, &CHalconMFCDlg::OnNMCustomdrawSliderThreshold)
	ON_WM_HSCROLL()
	ON_EN_CHANGE(IDC_EDIT_THRESHOLD, &CHalconMFCDlg::OnEnChangeEditThreshold)
END_MESSAGE_MAP()

//.....

//....
//
BOOL CHalconMFCDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。
	//......
	
	//......
	// TODO: 在此添加额外的初始化代码

	m_ctrlSlider.SetRange(5, 255);    //设置滑块位置的最大值和最小值
	m_ctrlSlider.SetPos(125);         //设置滑块的默认当前位置

	//初始化图像加载标识
	m_IsEmpty = FALSE;
}
//两个button
void CHalconMFCDlg::OnBnClickedButtonReadImg()
{
	// TODO: 在此添加控件通知处理程序代码
	m_IsEmpty = TRUE;
	CRect rect;
	pWnd = GetDlgItem(IDC_STATIC_ORIGINAL_IMG);
	picture1_WindowID = (Hlong)pWnd->m_hWnd;
	pWnd->GetWindowRect(&rect);

	ReadImage(&ho_Image, "fabrik");
	GetImageSize(ho_Image, &hv_Width, &hv_Height);
	OpenWindow(0, 0, rect.Width(), rect.Height(), picture1_WindowID, "visible", "", &hv_WindowID);
	HDevWindowStack::Push(hv_WindowID);
	if (HDevWindowStack::IsOpen())
		SetDraw(HDevWindowStack::GetActive(), "margin");
	if (HDevWindowStack::IsOpen())
		SetLineWidth(HDevWindowStack::GetActive(), 3);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_Image, HDevWindowStack::GetActive());
}


void CHalconMFCDlg::OnBnClickedButtonProcessImg()
{
	// TODO: 在此添加控件通知处理程序代码
	CRect Rect;
	pWnd = GetDlgItem(IDC_STATIC_PROCESS_IMAGE);
	picture2_WindowID = (Hlong)pWnd->m_hWnd;
	pWnd->GetWindowRect(&Rect);
	OpenWindow(0, 0, Rect.Width(), Rect.Height(), picture2_WindowID, "visible", "", &hv_WindowID);
	HDevWindowStack::Push(hv_WindowID);
	//Detect edges
	SobelAmp(ho_Image, &ho_EdgeAmplitude, "thin_sum_abs", 3);
	Threshold(ho_EdgeAmplitude, &ho_Edges, 5, 255);
	BackgroundSeg(ho_Edges, &ho_BackgroundRegions);
	//Fill up holes in regions based on shape feature 'area'
	FillUpShape(ho_BackgroundRegions, &ho_RegionFillUp, "area", 1, 40);
	if (HDevWindowStack::IsOpen())
		ClearWindow(HDevWindowStack::GetActive());
	if (HDevWindowStack::IsOpen())
		SetColored(HDevWindowStack::GetActive(), 6);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_RegionFillUp, HDevWindowStack::GetActive());
}
//滑块
void CHalconMFCDlg::OnNMCustomdrawSliderThreshold(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	int nPos = m_ctrlSlider.GetPos();

	CString str = _T("");
	str.Format(_T("%d"), nPos);
	SetDlgItemText(IDC_EDIT_THRESHOLD, str);
}


void CHalconMFCDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
	CSliderCtrl *pSlidCtrl = (CSliderCtrl*)GetDlgItem(IDC_SLIDER_THRESHOLD);
	m_threshold = pSlidCtrl->GetPos();       //取得当前位置值
	if (m_IsEmpty == TRUE) {
		//SetColor(picture1_WindowID, "red");
		SobelAmp(ho_Image, &ho_EdgeAmplitude, "thin_sum_abs", 3);
		Threshold(ho_EdgeAmplitude, &ho_Edges, 5, m_threshold);
		BackgroundSeg(ho_Edges, &ho_BackgroundRegions);
		//Fill up holes in regions based on shape feature 'area'
		FillUpShape(ho_BackgroundRegions, &ho_RegionFillUp, "area", 1, 40);
		if (HDevWindowStack::IsOpen())
			ClearWindow(HDevWindowStack::GetActive());
		if (HDevWindowStack::IsOpen())
			SetColored(HDevWindowStack::GetActive(), 6);
		if (HDevWindowStack::IsOpen())
			DispObj(ho_RegionFillUp, HDevWindowStack::GetActive());
	
	}
	else
	{
		MessageBox(_T("请加载图像!"));
	}

}

void CHalconMFCDlg::OnEnChangeEditThreshold()
{
	// TODO:  如果该控件是 RICHEDIT 控件,它将不
	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask(),
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
}

总结