引言
使用MFC联合Halcon,将HDevelop中的演示结果用MFC中对话框的形式显示
一、结果
1.1 Halcon演示结果
1.2 MFC演示结果
二、Halcon代码
* This example demonstrates the use of the optical flow operators.
* By calculating the optical flow between two images, the
* position, speed, and movement direction of particles are calculated.
*
dev_update_off ()
dev_close_window ()
*
read_image (Image1, 'hydraulic_engineering/hydraulic_engineering_01')
dev_open_window_fit_image (Image1, 0, 0, -1, -1, WindowHandle)
*
dev_set_draw ('margin')
RCenter := -1
CCenter := -1
MeanR := 0
MeanC := 0
tanDir := 0
ArrowLength := 15
MinLength := 0.375
*
for Index := 2 to 50 by 1
read_image (Image2, 'hydraulic_engineering/hydraulic_engineering_' + Index$'02')
*
* Calculate the optical flow between two images
optical_flow_mg (Image1, Image2, VectorField, 'clg', 1, 1, 1000, 5, 'default_parameters', 'fast')
vector_field_length (VectorField, LengthImage, 'squared_length')
*
* Estimate the region with moving particles using the length
* of the vectors of the calculated vector field
min_max_gray (LengthImage, LengthImage, 0, Min, MaxLength, Range)
if (MaxLength > MinLength)
threshold (LengthImage, ROI, MinLength, MaxLength)
*
* Find the position of particles in the original image using
* an estimated ROI
dilation_circle (ROI, RegionDilation, 3.5)
reduce_domain (Image2, RegionDilation, ImageReduced)
local_max_sub_pix (ImageReduced, 'facet', 1.0, 4, Row, Column)
*
dev_set_color ('cyan')
dev_set_line_width (2)
if (|Row| > 0)
gen_region_points (Points, Row, Column)
connection (Points, ConnectedRegions)
dilation_circle (ConnectedRegions, PointsDilated, 2.5)
*
* Display found particles and their movement directions
count_obj (PointsDilated, NumberReg)
dev_display (Image2)
dev_display (PointsDilated)
for J := 1 to NumberReg by 1
select_obj (PointsDilated, SelectedRegions, J)
*
* Estimate the speed of the particles
reduce_domain (VectorField, SelectedRegions, ImageReducedVF)
vector_field_to_real (ImageReducedVF, RowImage, ColumnImage)
intensity (ColumnImage, ColumnImage, MeanC, Deviation)
intensity (RowImage, RowImage, MeanR, Deviation)
Length := sqrt(MeanR * MeanR + MeanC * MeanC)
gen_arrow_contour_xld (Arrow, Row[J - 1], Column[J - 1], Row[J - 1] + MeanR / Length * ArrowLength, Column[J - 1] + MeanC / Length * ArrowLength, 5, 10)
dev_display (Arrow)
endfor
endif
endif
copy_obj (Image2, Image1, 1, 1)
endfor
三、MFC源代码
1.头文件主要代码
public:
MyAssist myassist;
HTuple picture1_WindowID,picture2_WindowID;
CWnd *pWnd;
// Local iconic variables
HObject ho_Image1, ho_Image2, ho_VectorField;
HObject ho_LengthImage, ho_ROI, ho_RegionDilation, ho_ImageReduced;
HObject ho_Points, ho_ConnectedRegions, ho_PointsDilated;
HObject ho_SelectedRegions, ho_ImageReducedVF, ho_RowImage;
HObject ho_ColumnImage, ho_Arrow;
// Local control variables
HTuple hv_WindowHandle, hv_RCenter, hv_CCenter;
HTuple hv_MeanR, hv_MeanC, hv_tanDir, hv_ArrowLength, hv_MinLength;
HTuple hv_Index, hv_Min, hv_MaxLength, hv_Range, hv_Row;
HTuple hv_Column, hv_NumberReg, hv_J, hv_Deviation, hv_Length;
public:
afx_msg void OnBnClickedButtonReadImg();
2.源文件主要代码
void CHalconMFCDlg::OnBnClickedButtonReadImg()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect;
pWnd = GetDlgItem(IDC_STATIC_ORIGINAL_IMG);
picture1_WindowID = (Hlong)pWnd->m_hWnd;
pWnd->GetWindowRect(&rect);
//This example demonstrates the use of the optical flow operators.
//By calculating the optical flow between two images, the
//position, speed, and movement direction of particles are calculated.
//
myassist.dev_update_off();
//
ReadImage(&ho_Image1, "hydraulic_engineering/hydraulic_engineering_01");
//myassist.dev_open_window_fit_image(ho_Image1, 0, 0, -1, -1, &hv_WindowHandle);
OpenWindow(0, 0, rect.Width(), rect.Height(), picture1_WindowID, "visible", "", &hv_WindowHandle);
HDevWindowStack::Push(hv_WindowHandle);
//
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(), "margin");
hv_RCenter = -1;
hv_CCenter = -1;
hv_MeanR = 0;
hv_MeanC = 0;
hv_tanDir = 0;
hv_ArrowLength = 15;
hv_MinLength = 0.375;
//
for (hv_Index = 2; hv_Index <= 50; hv_Index += 1)
{
ReadImage(&ho_Image2, "hydraulic_engineering/hydraulic_engineering_" + (hv_Index.TupleString("02")));
//
//Calculate the optical flow between two images
OpticalFlowMg(ho_Image1, ho_Image2, &ho_VectorField, "clg", 1, 1, 1000, 5, "default_parameters",
"fast");
VectorFieldLength(ho_VectorField, &ho_LengthImage, "squared_length");
//
//Estimate the region with moving particles using the length
//of the vectors of the calculated vector field
MinMaxGray(ho_LengthImage, ho_LengthImage, 0, &hv_Min, &hv_MaxLength, &hv_Range);
if (0 != (hv_MaxLength > hv_MinLength))
{
Threshold(ho_LengthImage, &ho_ROI, hv_MinLength, hv_MaxLength);
//
//Find the position of particles in the original image using
//an estimated ROI
DilationCircle(ho_ROI, &ho_RegionDilation, 3.5);
ReduceDomain(ho_Image2, ho_RegionDilation, &ho_ImageReduced);
LocalMaxSubPix(ho_ImageReduced, "facet", 1.0, 4, &hv_Row, &hv_Column);
//
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "cyan");
if (HDevWindowStack::IsOpen())
SetLineWidth(HDevWindowStack::GetActive(), 2);
if (0 != ((hv_Row.TupleLength()) > 0))
{
GenRegionPoints(&ho_Points, hv_Row, hv_Column);
Connection(ho_Points, &ho_ConnectedRegions);
DilationCircle(ho_ConnectedRegions, &ho_PointsDilated, 2.5);
//
//Display found particles and their movement directions
CountObj(ho_PointsDilated, &hv_NumberReg);
if (HDevWindowStack::IsOpen())
DispObj(ho_Image2, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
DispObj(ho_PointsDilated, HDevWindowStack::GetActive());
{
HTuple end_val49 = hv_NumberReg;
HTuple step_val49 = 1;
for (hv_J = 1; hv_J.Continue(end_val49, step_val49); hv_J += step_val49)
{
SelectObj(ho_PointsDilated, &ho_SelectedRegions, hv_J);
//
//Estimate the speed of the particles
ReduceDomain(ho_VectorField, ho_SelectedRegions, &ho_ImageReducedVF);
VectorFieldToReal(ho_ImageReducedVF, &ho_RowImage, &ho_ColumnImage);
Intensity(ho_ColumnImage, ho_ColumnImage, &hv_MeanC, &hv_Deviation);
Intensity(ho_RowImage, ho_RowImage, &hv_MeanR, &hv_Deviation);
hv_Length = ((hv_MeanR*hv_MeanR) + (hv_MeanC*hv_MeanC)).TupleSqrt();
myassist.gen_arrow_contour_xld(&ho_Arrow, HTuple(hv_Row[hv_J - 1]), HTuple(hv_Column[hv_J - 1]),
HTuple(hv_Row[hv_J - 1]) + ((hv_MeanR / hv_Length)*hv_ArrowLength), HTuple(hv_Column[hv_J - 1]) + ((hv_MeanC / hv_Length)*hv_ArrowLength),
5, 10);
if (HDevWindowStack::IsOpen())
DispObj(ho_Arrow, HDevWindowStack::GetActive());
}
}
}
}
CopyObj(ho_Image2, &ho_Image1, 1, 1);
}
}