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);
};