void Ctest4Dlg::CreateImageWindow()
{
CRect rect; //设置一块区域
HTuple hv_Exception;
GetDlgItem(IDC_PIC)->GetClientRect(&rect); //获取显示控件的指针
HWND hrect = GetDlgItem(IDC_PIC)->m_hWnd; //获取控件的句柄
HTuple Row = (HTuple)rect.top; //获取区域顶端的行坐标
HTuple Column = (HTuple)rect.left; //获取区域左边的列坐标
HTuple Width = (HTuple)rect.Width(); //获取区域的宽度信息
HTuple Height = (HTuple)rect.Height(); //获取区域的高度信息
try
{
SetWindowAttr("background_color", "black"); //设置背景颜色为黑色
OpenWindow(Row, Column, Width, Height, (Hlong)hrect, "visiable", "", &WindowHandle);
//按区域大小打开一个窗口
}
catch (HalconCpp::HException &HDecExpDefauleException)
{
HDecExpDefauleException.ToHTuple(&hv_Exception);
throw HalconCpp::HException(hv_Exception); //捕捉错误
}
}
void Ctest4Dlg::OnPlayVideo()
{
AfxBeginThread(StratCameraTest, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL); //开启一个线程
}
UINT Ctest4Dlg::StartCameraTest(LPVOID pParam)
{
Ctest4Dlg *pDlg = (Ctest4Dlg*)pParam;
OpenFramegrabber(); //打开相机函数
GrabImageStart(hv_AcqHandle, -1); //获得相机句柄
pDlg->StartImageState = true;
while (pDlg->StartCameraTest)
{
GrabImageAsync(&pDlg->ho_Image, hv_AcqHandle, -1);//调用相机采集函数
HTuple hv_AcqHandle;
//获得图像大小
HTuple hv_Width, hv_Height;
getImageSize(pDlg->ho_Image, &hv_Width, &hv_Height);
//通过改变图像的缩放来适应图像在区域正常显示
SetPart(pDlg->WindowHandle,ho_Image, 0, 0, hv_Height, hv_Width);
//在窗口上显示图像
DispObj(pDlg->ho_Image, pDlg->WindowHandle);
}
CloseFramegrabber(hv_AcqHandle); //关闭相机
AfxEndThread(0); //结束线程
return 0;
}
将打开相机的程序写入到主程序的初始化程序中
灰色图转换为vc变量
图像显示:
准备:
在主程序的.h和.cpp文件中添加以下代码:
#include "HalconCpp.h"
using namespace HalconCpp;
1.创建界面,添加图像采集和图像处理按钮,并添加picture_control控件,修改图片控件ID为IDC_PIC_STATIC。
2.用vs打开halcon程序,选择action函数,将action中的声明添加到主程序的.h文件中:
public:
afx_msg void OnBnClickedButton1();
HObject ho_Image, ho_ImageInverted, ho_ImageBandpass;
HObject ho_ImageFFT, ho_ImageConvol, ho_Lines, ho_Region;
HObject ho_ConnectedRegions, ho_SelectedRegions, ho_RegionDilation;
HObject ho_Skeleton, ho_Errors, ho_RegionUnion, ho_ImageReduced;
HObject ho_LinesXLD, ho_UnionContours, ho_SelectedXLD, ho_RegionXLD;
HObject ho_RegionScratches;
// Local control variables
HTuple hv_Width, hv_Height, hv_WindowHandle;
afx_msg void OnBnClickedButton2();
};
3.双击图片采集按钮,添加按钮点击事件,并添加以下代码,更改图像控件ID为IDC_PIC_STATIC:、
void CCircleColuDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
/*dev_update_off();
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());*/
//读取图像
ReadImage(&ho_Image, "C:/Users/Administrator/Desktop/Image_20190717102710902.bmp");
InvertImage(ho_Image, &ho_ImageInverted);
GetImageSize(ho_Image, &hv_Width, &hv_Height);
//SetWindowAttr("background_color", "black");
//OpenWindow(0, 0, hv_Width, hv_Height, 0, "visible", "", &hv_WindowHandle);
/*HDevWindowStack::Push(hv_WindowHandle);
set_display_font(hv_WindowHandle, 16, "mono", "true", "false");
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());*/
CRect rtWindow;
HWND hImgWnd = GetDlgItem(IDC_PIC_STATIC)->m_hWnd;
GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&rtWindow);
HTuple m_htWindow;
OpenWindow(rtWindow.left, rtWindow.top, rtWindow.Width(), rtWindow.Height(), (Hlong)hImgWnd, "visible", "", &m_htWindow);
SetPart(m_htWindow, 0, 0, hv_Height, hv_Width );//
DispObj(ho_Image, m_htWindow);
}
4.双击图像处理按钮,添加点击事件,在最后原图要先显示,缺陷标出来的图像跟在原图后面显示:
void CCircleColuDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
GenSinBandpass(&ho_ImageBandpass, 0.4, "none", "rft", hv_Width, hv_Height);
//快速傅里叶变换
RftGeneric(ho_ImageInverted, &ho_ImageFFT, "to_freq", "none", "complex", hv_Width);
//图像卷积
ConvolFft(ho_ImageFFT, ho_ImageBandpass, &ho_ImageConvol);
//快速傅里叶变换,转换图像到空间域及byte类型
RftGeneric(ho_ImageConvol, &ho_Lines, "from_freq", "n", "byte", hv_Width);
//
//通过形态学实现划伤分割
Threshold(ho_Lines, &ho_Region, 5, 255);
Connection(ho_Region, &ho_ConnectedRegions);
//select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5, 5000)
SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, (HTuple("area").Append("column")),
"and", (HTuple(142.31).Append(592.98)), (HTuple(22438.3).Append(2718.22)));
DilationCircle(ho_SelectedRegions, &ho_RegionDilation, 7);
//对膨胀后的区域进行求骨架
Skeleton(ho_RegionDilation, &ho_Skeleton);
//对获取的骨架区域进行连通处理
Connection(ho_Skeleton, &ho_Errors);
Union1(ho_RegionDilation, &ho_RegionUnion);
//缩小图像域
ReduceDomain(ho_Image, ho_RegionUnion, &ho_ImageReduced);
//检测线条及宽度
LinesGauss(ho_ImageReduced, &ho_LinesXLD, 0.8, 3, 10, "dark", "false", "bar-shaped",
"false");
//把在一条线上的轮廓连起来
UnionCollinearContoursXld(ho_LinesXLD, &ho_UnionContours, 40, 3, 3, 0.2, "attr_keep");
//根据形状特征筛选线条轮廓,轮廓总长度在15-1000之间的
SelectShapeXld(ho_UnionContours, &ho_SelectedXLD, "area", "and", 10, 99999);
//select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 15, 1000)
GenRegionContourXld(ho_SelectedXLD, &ho_RegionXLD, "filled");
Union1(ho_RegionXLD, &ho_RegionUnion);
//膨胀,把有划痕的区域圈出来
DilationCircle(ho_RegionUnion, &ho_RegionScratches, 8);
//
//Display the results
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(), "margin");
if (HDevWindowStack::IsOpen())
SetLineWidth(HDevWindowStack::GetActive(), 3);
if (HDevWindowStack::IsOpen())
SetColored(HDevWindowStack::GetActive(), 12);
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
DispObj(ho_RegionScratches, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "red");
CRect rtWindow;
HWND hImgWnd = GetDlgItem(IDC_PIC_STATIC)->m_hWnd;
GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&rtWindow);
HTuple m_htWindow;
OpenWindow(rtWindow.left, rtWindow.top, rtWindow.Width(), rtWindow.Height(), (Hlong)hImgWnd, "visible", "", &m_htWindow);
SetPart(m_htWindow, 0, 0, hv_Height, hv_Width);//
DispObj(ho_Image, m_htWindow);
DispObj(ho_RegionScratches, m_htWindow);
}