一、实现功能
单击主界面按钮弹出子对话框,里面可以实时制作模板,也可以离线制作模板,制作的模板存在指定的目录,同时要求输入模板的型号,这样存储模板时会将型号与模板绑定,显示模板时可以将存储的路径进行显示,同时将模板型号实时显示。
二、头文件
#pragma once
#include "HalconCpp.h"
using namespace HalconCpp;
// MODEL 对话框
class MODEL : public CDialogEx
{
DECLARE_DYNAMIC(MODEL)
public:
MODEL(CWnd* pParent = NULL); // 标准构造函数
virtual ~MODEL();
// 对话框数据
enum { IDD = IDD_MODEL };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton14();
afx_msg void OnBnClickedButton15();
afx_msg void OnBnClickedButton16();
afx_msg void OnBnClickedButton17();
virtual BOOL OnInitDialog();
afx_msg void OnTimer(UINT_PTR nIDEvent);
CString m_num;
CString m_loadpath;
afx_msg void OnBnClickedButton19();
CString m_modelname;
};
三、源文件
// MODEL.cpp : 实现文件
//
#include "stdafx.h"
#include "WSBCR.h"
#include "MODEL.h"
#include "afxdialogex.h"
#include <sstream> //数字转字符串
using namespace std;
HObject ho_Image1 ,ho_Image2, ho_Region1, ho_ConnectedRegions1;
HObject ho_circleout1, ho_ImageReduced1, ho_model1, ho_ImageSearch2, ho_ImageSearch3;
HObject ho_Contours1;
HTuple hv_Row1, hv_Column1, hv_Radius1, hv_AcqHandle1;
HTuple width1, height1, hv_WindowHandle1,hv_WindowHandle2;
//unsigned int modelnum, passnum, failnum, detnum;
// MODEL 对话框
IMPLEMENT_DYNAMIC(MODEL, CDialogEx)
MODEL::MODEL(CWnd* pParent /*=NULL*/)
: CDialogEx(MODEL::IDD, pParent)
, m_num(_T(""))
, m_loadpath(_T(""))
, m_modelname(_T(""))
{
}
MODEL::~MODEL()
{
}
void MODEL::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_num);
DDX_Text(pDX, IDC_EDIT2, m_loadpath);
DDX_Text(pDX, IDC_EDIT4, m_modelname);
}
BEGIN_MESSAGE_MAP(MODEL, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON14, &MODEL::OnBnClickedButton14)
ON_BN_CLICKED(IDC_BUTTON15, &MODEL::OnBnClickedButton15)
ON_BN_CLICKED(IDC_BUTTON16, &MODEL::OnBnClickedButton16)
ON_BN_CLICKED(IDC_BUTTON17, &MODEL::OnBnClickedButton17)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON19, &MODEL::OnBnClickedButton19)
END_MESSAGE_MAP()
// MODEL 消息处理程序
BOOL MODEL::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
CRect rtWindow;
HWND hImgWnd = GetDlgItem(IDC_PIC1)->m_hWnd;
GetDlgItem(IDC_PIC1)->GetClientRect(&rtWindow);
SetWindowAttr("background_color", "white");
OpenWindow(rtWindow.left, rtWindow.top, rtWindow.Width(), rtWindow.Height(), (Hlong)hImgWnd, "visible", "", &hv_WindowHandle1);
SetColor(hv_WindowHandle1, "red");
SetLineWidth(hv_WindowHandle1, 3);
CRect rtWindow1;
HWND hImgWnd1 = GetDlgItem(IDC_PIC2)->m_hWnd;
GetDlgItem(IDC_PIC2)->GetClientRect(&rtWindow1);
OpenWindow(rtWindow1.left, rtWindow1.top, rtWindow1.Width(), rtWindow1.Height(), (Hlong)hImgWnd1, "visible", "", &hv_WindowHandle2);
SetWindowAttr("background_color", "white");
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void MODEL::OnBnClickedButton14()
{
// TODO: 在此添加控件通知处理程序代码
OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "interlaced", 8, "gray", -1, "false",
"HV-xx51", "1", 1, -1, &hv_AcqHandle1);
GrabImageStart(hv_AcqHandle1, -1);
GrabImageAsync(&ho_Image1, hv_AcqHandle1, -1);
GetImageSize(ho_Image1, &height1, &width1);
SetPart(hv_WindowHandle1, 0, 0, width1, height1);
DispObj(ho_Image1, hv_WindowHandle1);
CloseFramegrabber(hv_AcqHandle1);
SetTimer(1, 100, NULL);
}
void MODEL::OnBnClickedButton15()
{
// TODO: 在此添加控件通知处理程序代码
KillTimer(1);
char* pcsun = "图片文件(*.bmp *.png *.jpg)|*.bmp;*.png;*jpg|All Files (*.*)|*.*||";
CFileDialog OpenDialog(TRUE, NULL, 0, OFN_OVERWRITEPROMPT, pcsun, NULL);
if (OpenDialog.DoModal() == IDCANCEL) return; //返回带文件名的路径,并传递给编辑控件变量
CString str = OpenDialog.GetPathName();
//CString str = "C:/Users/Administrator/Desktop/1.png";
char* ch = (char*)LPCTSTR(str);
ReadImage(&ho_Image1, ch);
//ReadImage(&ho_ImageSearch2, "C:/Users/Administrator/Desktop/电池字符识别分类/02图片/有无检测/2.jpg");
GetImageSize(ho_Image1, &height1, &width1);
SetPart(hv_WindowHandle1, 0, 0, width1, height1);
DispObj(ho_Image1, hv_WindowHandle1);
}
int imgnumber1 = 1;
void MODEL::OnBnClickedButton16()
{
// TODO: 在此添加控件通知处理程序代码
KillTimer(1);
//HTuple width1, height1;
ReadImage(&ho_Image2, "res/背景.png"); //防止残留,所以加了一个白板背景
GetImageSize(ho_Image2, &height1, &width1);
SetPart(hv_WindowHandle2, 0, 0, width1, height1);
DispObj(ho_Image2, hv_WindowHandle2);
MessageBox("请用鼠标选取ROI区域,单击右键完成选取!");
DrawCircle(hv_WindowHandle1, &hv_Row1, &hv_Column1, &hv_Radius1);
GenCircle(&ho_circleout1, hv_Row1, hv_Column1, hv_Radius1);
ReduceDomain(ho_Image1, ho_circleout1, & ho_ImageReduced1);
HTuple width1, height1;
GetImageSize(ho_ImageReduced1, &height1, &width1);
SetPart(hv_WindowHandle2, 0, 0, width1, height1);
DispObj(ho_ImageReduced1, hv_WindowHandle2);
/*SetDlgItemText(IDC_EDIT4, m_num);
UpdateData(false);*/
MessageBox("完成选取,请输入型号后点击“保存模板”按钮!");
}
void MODEL::OnBnClickedButton17()
{
// TODO: 在此添加控件通知处理程序代码
/*CString str4;
str4 = "LR001";*/
UpdateData(TRUE); //用于将屏幕上控件中的数据交换到变量中 UpdateData(false);//用于将数据在屏幕中对应控件中显示出来
char str3[200];
char* str1 = "C:/Users/Administrator/Desktop/电池字符识别分类/02图片/01模板/";
char* str2 = str1;
strcpy(str3, str1);
strcat(str3, m_num); //型号显示
char* str = str3;
//filepath1 = "C:/Users/Administrator/Desktop/电池字符识别分类/02图片/有无检测/";
//WriteImage(ho_ImageReduced1, "png", 0, "C:/Users/Administrator/Desktop" + filepath2[0] + filepath1[0] + filepath2[1] + filepath2[2] + filepath2[3] + filepath2[4]);
WriteImage(ho_ImageReduced1, "png", 0, str);
MessageBox("模板已存至指定目录!");
memset(str3, 0, sizeof(str3) / sizeof(char));
}
void MODEL::OnBnClickedButton19()
{
// TODO: 在此添加控件通知处理程序代码
ReadImage(&ho_Image1, "res/背景.png"); //防止残留,所以加了一个白板背景
GetImageSize(ho_Image1, &height1, &width1);
SetPart(hv_WindowHandle2, 0, 0, width1, height1);
DispObj(ho_Image1, hv_WindowHandle2);
char* pcsun = "图片文件(*.bmp *.png *.jpg)|*.bmp;*.png;*jpg|All Files (*.*)|*.*||";
CFileDialog OpenDialog(TRUE, NULL, 0, OFN_OVERWRITEPROMPT, pcsun, NULL);
if (OpenDialog.DoModal() == IDCANCEL) return; //返回带文件名的路径,并传递给编辑控件变量
CString str = OpenDialog.GetPathName();
//CString str = "C:/Users/Administrator/Desktop/1.png";
CString str1;
char* ch = (char*)LPCTSTR(str);
str1 = str.Left(str.Find('.'));
str1 = str1.Right(str1.GetLength() - 1 - str1.ReverseFind('\\')); //路径是双反斜杠
//MessageBox(str, MB_OK, 0);
m_loadpath = str;
m_modelname = str1;
UpdateData(false);
ReadImage(&ho_model1, ch);
HTuple width1, height1;
GetImageSize(ho_model1, &height1, &width1);
SetPart(hv_WindowHandle2, 0, 0, width1, height1);
DispObj(ho_model1, hv_WindowHandle2);
/*CRect rtWindow;
HWND hImgWnd = GetDlgItem(IDC_PIC2)->m_hWnd;
GetDlgItem(IDC_PIC2)->GetClientRect(&rtWindow);
OpenWindow(rtWindow.left, rtWindow.top, rtWindow.Width(), rtWindow.Height(), (Hlong)hImgWnd, "visible", "", &hv_WindowHandle11);
SetPart(hv_WindowHandle2, 0, 0, width1, height1);
DispObj(ho_model1, hv_WindowHandle2);*/
//failnum = 1;
}
void MODEL::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "interlaced", 8, "gray", -1, "false",
"HV-xx51", "1", 1, -1, &hv_AcqHandle1);
GrabImageStart(hv_AcqHandle1, -1);
GrabImageAsync(&ho_Image1, hv_AcqHandle1, -1);
GetImageSize(ho_Image1, &height1, &width1);
SetPart(hv_WindowHandle1, 0, 0, width1, height1);
DispObj(ho_Image1, hv_WindowHandle1);
CloseFramegrabber(hv_AcqHandle1);
CDialogEx::OnTimer(nIDEvent);
}
四、关键创新点
1.存储模板时,将输入的型号作为模板的名称,如LR44H.png
2.显示模板时,将模板图片的名称提取出来显示为模板名称。
3.在图片控件上进行图片显示时,由于png格式的图片是透明的,所以多次显示时会有背景的残留问题,后来仔细一想之后就直接加了一个白板背景,每次点击模板显示时就覆盖一次白板背景。
五、运行效果