MFC与HALCON混合编程一之打开图像—edge_segments

引言

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


一、结果(打开图像_简单处理)

1.1 Halcon演示结果

原始图
在这里插入图片描述
处理后
在这里插入图片描述

1.2 MFC演示结果

读取图像

在这里插入图片描述
边缘提取
在这里插入图片描述


二、Halcon代码

* edge_segments.hdev: extracting connected edges segments
* 
dev_update_off ()
dev_close_window ()
* ****
* step: acquire image
* ****
read_image (Image, 'mreut')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowID)
set_display_font (WindowID, 12, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Image)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: filter image
* ****
edges_image (Image, ImaAmp, ImaDir, 'lanser2', 0.5, 'nms', 20, 40)
dev_display (ImaAmp)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: extract edges
* ****
threshold (ImaAmp, Region, 1, 255)
connection (Region, ConnectedRegions)
dev_clear_window ()
dev_set_colored (12)
dev_display (ConnectedRegions)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: process edges
* ****
dev_clear_window ()
count_obj (ConnectedRegions, Number)
gen_empty_obj (XLDContours)
for i := 1 to Number by 1
    select_obj (ConnectedRegions, SingleEdgeObject, i)
    split_skeleton_lines (SingleEdgeObject, 2, BeginRow, BeginCol, EndRow, EndCol)
    for k := 0 to |BeginRow| - 1 by 1
        gen_contour_polygon_xld (Contour, [BeginRow[k],EndRow[k]], [BeginCol[k],EndCol[k]])
        concat_obj (XLDContours, Contour, XLDContours)
    endfor
endfor
dev_display (XLDContours)

三、MFC源代码

1.halcon导出C++

// Main procedure 
void action()
{

  // Local iconic variables
  HObject  ho_Image, ho_ImaAmp, ho_ImaDir, ho_Region;
  HObject  ho_ConnectedRegions, ho_XLDContours, ho_SingleEdgeObject;
  HObject  ho_Contour;

  // Local control variables
  HTuple  hv_Width, hv_Height, hv_WindowID, hv_Number;
  HTuple  hv_i, hv_BeginRow, hv_BeginCol, hv_EndRow, hv_EndCol;
  HTuple  hv_k;

  //edge_segments.hdev: extracting connected edges segments
  //
  dev_update_off();
  if (HDevWindowStack::IsOpen())
    CloseWindow(HDevWindowStack::Pop());
  //****
  //step: acquire image
  //****
  ReadImage(&ho_Image, "mreut");
  GetImageSize(ho_Image, &hv_Width, &hv_Height);
  dev_open_window_fit_image(ho_Image, 0, 0, hv_Width, hv_Height, &hv_WindowID);
  set_display_font(hv_WindowID, 12, "mono", "true", "false");
  if (HDevWindowStack::IsOpen())
    SetDraw(HDevWindowStack::GetActive(),"margin");
  if (HDevWindowStack::IsOpen())
    SetLineWidth(HDevWindowStack::GetActive(),3);
  if (HDevWindowStack::IsOpen())
    DispObj(ho_Image, HDevWindowStack::GetActive());
  disp_continue_message(hv_WindowID, "black", "true");
  // stop(); only in hdevelop
  //****
  //step: filter image
  //****
  EdgesImage(ho_Image, &ho_ImaAmp, &ho_ImaDir, "lanser2", 0.5, "nms", 20, 40);
  if (HDevWindowStack::IsOpen())
    DispObj(ho_ImaAmp, HDevWindowStack::GetActive());
  disp_continue_message(hv_WindowID, "black", "true");
  // stop(); only in hdevelop
  //****
  //step: extract edges
  //****
  Threshold(ho_ImaAmp, &ho_Region, 1, 255);
  Connection(ho_Region, &ho_ConnectedRegions);
  if (HDevWindowStack::IsOpen())
    ClearWindow(HDevWindowStack::GetActive());
  if (HDevWindowStack::IsOpen())
    SetColored(HDevWindowStack::GetActive(),12);
  if (HDevWindowStack::IsOpen())
    DispObj(ho_ConnectedRegions, HDevWindowStack::GetActive());
  disp_continue_message(hv_WindowID, "black", "true");
  // stop(); only in hdevelop
  //****
  //step: process edges
  //****
  if (HDevWindowStack::IsOpen())
    ClearWindow(HDevWindowStack::GetActive());
  CountObj(ho_ConnectedRegions, &hv_Number);
  GenEmptyObj(&ho_XLDContours);
  {
  HTuple end_val39 = hv_Number;
  HTuple step_val39 = 1;
  for (hv_i=1; hv_i.Continue(end_val39, step_val39); hv_i += step_val39)
  {
    SelectObj(ho_ConnectedRegions, &ho_SingleEdgeObject, hv_i);
    SplitSkeletonLines(ho_SingleEdgeObject, 2, &hv_BeginRow, &hv_BeginCol, &hv_EndRow, 
        &hv_EndCol);
    {
    HTuple end_val42 = (hv_BeginRow.TupleLength())-1;
    HTuple step_val42 = 1;
    for (hv_k=0; hv_k.Continue(end_val42, step_val42); hv_k += step_val42)
    {
      GenContourPolygonXld(&ho_Contour, HTuple(hv_BeginRow[hv_k]).TupleConcat(HTuple(hv_EndRow[hv_k])), 
          HTuple(hv_BeginCol[hv_k]).TupleConcat(HTuple(hv_EndCol[hv_k])));
      ConcatObj(ho_XLDContours, ho_Contour, &ho_XLDContours);
    }
    }
  }
  }
  if (HDevWindowStack::IsOpen())
    DispObj(ho_XLDContours, HDevWindowStack::GetActive());
}

将以上转换后的代码运用到MFC工程中

1、新建MFC对话框工程(具体过程不在赘述)

2、添加文件包含
用到的halcon中的处理算子,故而必须在所建工程的头文件中添加

#include <HalconCpp.h>
using namespace HalconCpp;

3、修改对话框,添加两个按钮,增加响应函数,设计的界面如下:

在这里插入图片描述

2.头文件主要代码

// HalconMFCDlg.h: 头文件
//

#pragma once
#include"OhterAssist.h"
#include <HalconCpp.h>
using namespace HalconCpp;


// CHalconMFCDlg 对话框
class CHalconMFCDlg : public CDialogEx
{
// 构造
public:
	CHalconMFCDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_HALCONMFC_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	MyAssist myassist;
	// Local iconic variables
	HObject  ho_Image, ho_ImaAmp, ho_ImaDir, ho_Region;
	HObject  ho_ConnectedRegions, ho_XLDContours, ho_SingleEdgeObject;
	HObject  ho_Contour;

	// Local control variables
	HTuple  hv_Width, hv_Height, hv_WindowID, hv_Number;
	HTuple  hv_i, hv_BeginRow, hv_BeginCol, hv_EndRow, hv_EndCol;
	HTuple  hv_k;
public:
	afx_msg void OnBnClickedButtonReadimage();
	afx_msg void OnBnClickedButtonProcessimage();
};

3.源文件主要代码


// HalconMFCDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "HalconMFC.h"
#include "HalconMFCDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CHalconMFCDlg 对话框
BEGIN_MESSAGE_MAP(CHalconMFCDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_READIMAGE, &CHalconMFCDlg::OnBnClickedButtonReadimage)
	ON_BN_CLICKED(IDC_BUTTON_PROCESSIMAGE, &CHalconMFCDlg::OnBnClickedButtonProcessimage)
END_MESSAGE_MAP()


void CHalconMFCDlg::OnBnClickedButtonReadimage()
{
	// TODO: 在此添加控件通知处理程序代码
	//****
    //step: acquire image
    //****
	ReadImage(&ho_Image, "mreut");
	GetImageSize(ho_Image, &hv_Width, &hv_Height);
	myassist.dev_open_window_fit_image(ho_Image, 0, 0, hv_Width, hv_Height, &hv_WindowID);
	myassist.set_display_font(hv_WindowID, 12, "mono", "true", "false");
	if (HDevWindowStack::IsOpen())
		SetDraw(HDevWindowStack::GetActive(), "margin");
	if (HDevWindowStack::IsOpen())
		SetLineWidth(HDevWindowStack::GetActive(), 3);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_Image, HDevWindowStack::GetActive());
	//myassist.disp_continue_message(hv_WindowID, "black", "true");
}


void CHalconMFCDlg::OnBnClickedButtonProcessimage()
{
	// TODO: 在此添加控件通知处理程序代码
	 //****
     //step: filter image
     //****
	EdgesImage(ho_Image, &ho_ImaAmp, &ho_ImaDir, "lanser2", 0.5, "nms", 20, 40);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_ImaAmp, HDevWindowStack::GetActive());
	//myassist.disp_continue_message(hv_WindowID, "black", "true");
	// stop(); only in hdevelop
	//****
	//step: extract edges
	//****
	Threshold(ho_ImaAmp, &ho_Region, 1, 255);
	Connection(ho_Region, &ho_ConnectedRegions);
	if (HDevWindowStack::IsOpen())
		ClearWindow(HDevWindowStack::GetActive());
	if (HDevWindowStack::IsOpen())
		SetColored(HDevWindowStack::GetActive(), 12);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_ConnectedRegions, HDevWindowStack::GetActive());
	//myassist.disp_continue_message(hv_WindowID, "black", "true");
	// stop(); only in hdevelop
	//****
	//step: process edges
	//****
	if (HDevWindowStack::IsOpen())
		ClearWindow(HDevWindowStack::GetActive());
	CountObj(ho_ConnectedRegions, &hv_Number);
	GenEmptyObj(&ho_XLDContours);
	{
		HTuple end_val39 = hv_Number;
		HTuple step_val39 = 1;
		for (hv_i = 1; hv_i.Continue(end_val39, step_val39); hv_i += step_val39)
		{
			SelectObj(ho_ConnectedRegions, &ho_SingleEdgeObject, hv_i);
			SplitSkeletonLines(ho_SingleEdgeObject, 2, &hv_BeginRow, &hv_BeginCol, &hv_EndRow,
				&hv_EndCol);
			{
				HTuple end_val42 = (hv_BeginRow.TupleLength()) - 1;
				HTuple step_val42 = 1;
				for (hv_k = 0; hv_k.Continue(end_val42, step_val42); hv_k += step_val42)
				{
					GenContourPolygonXld(&ho_Contour, HTuple(hv_BeginRow[hv_k]).TupleConcat(HTuple(hv_EndRow[hv_k])),
						HTuple(hv_BeginCol[hv_k]).TupleConcat(HTuple(hv_EndCol[hv_k])));
					ConcatObj(ho_XLDContours, ho_Contour, &ho_XLDContours);
				}
			}
		}
	}
	if (HDevWindowStack::IsOpen())
		DispObj(ho_XLDContours, HDevWindowStack::GetActive());
}

NOTE

需要注意halcon和vs2017配置,MyAssist 类是将导出为C++的文件中的一些辅助函数进行了一些封装

//OhterAssist.h: 头文件
#pragma once
#include <HalconCpp.h>
using namespace HalconCpp;
class MyAssist
{
public:
	MyAssist();
	~MyAssist();
	void dev_open_window_fit_image(HObject ho_Image, HTuple hv_Row, HTuple hv_Column,
		HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle);
	// Chapter: Develop
	// Short Description: Switch dev_update_pc, dev_update_var and dev_update_window to 'off'. 
	void dev_update_off();
	// Chapter: Graphics / Text
	// Short Description: Set font independent of OS 
	void set_display_font(HTuple hv_WindowHandle, HTuple hv_Size, HTuple hv_Font, HTuple hv_Bold,
		HTuple hv_Slant);
	// Chapter: Graphics / Text
	// Short Description: This procedure displays 'Click 'Run' to continue' in the lower right corner of the screen. 
	void disp_continue_message(HTuple hv_WindowHandle, HTuple hv_Color, HTuple hv_Box);
	// Chapter: Graphics / Text
	// Short Description: This procedure writes a text message. 
	void disp_message(HTuple hv_WindowHandle, HTuple hv_String, HTuple hv_CoordSystem,
		HTuple hv_Row, HTuple hv_Column, HTuple hv_Color, HTuple hv_Box);
};


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值