#include "halcontool.h"
HalconTool::HalconTool() {
}
HalconTool::~HalconTool()
{
if(this->tempModelID != -1) {
ClearShapeModel(this->tempModelID);
}
}
void HalconTool::HInspectShapeModel(Mat mat, int contrast, Mat &res)
{
HInspectShapeModel(mat, contrast, res, Mat());
}
void HalconTool::HInspectShapeModel(Mat mat, int contrast, Mat &res, Mat mask)
{
HObject ho_Template, ho_ModeImages, ho_ModeRegions, ho_ModeContour;
MatC12HObject(mat, ho_Template);
if(mask.empty() == false) {
// imshow("mask", mask);
HObject ho_mask, ho_MaskRect;
MatC12HObject(mask, ho_mask);
HObject mask;
HTuple minGray = 1, maxGray = 255;
Threshold(ho_mask, &mask, minGray, maxGray);
ReduceDomain(ho_Template, mask, &ho_Template);
}
InspectShapeModel(ho_Template, &ho_ModeImages, &ho_ModeRegions, 1, contrast);
GenContourRegionXld(ho_ModeRegions, &ho_ModeContour, "border");
// ReduceDomain();
// HObject resImg;
// RegionToBin(ho_ModeRegions, &resImg, 255, 0, mat.cols, mat.rows);
cvtColor(mat, mat, COLOR_GRAY2BGR);
//遍历轮廓
HTuple hv_Number, hv_Row, hv_Column;
CountObj(ho_ModeContour, &hv_Number);
HObject item;
for(int i = 1; i < hv_Number.L(); i++) {
SelectObj(ho_ModeContour, &item, i);
GetContourXld(item, &hv_Row, &hv_Column);
for(int y = 1; y < hv_Row.Length(); y++) {
double dRow = hv_Row[y].D();
double dCol = hv_Column[y].D();
Vec3b &pix = mat.at<Vec3b>(dRow, dCol);
pix[2] = 255;
}
}
// imshow("", mat);
res = mat.clone();
}
void HalconTool::CreateTemplate(cv::Mat mat, string modelPath, int contrast)
{
CreateTemplate(mat, modelPath, contrast, Mat());
}
void HalconTool::CreateTemplate(Mat mat, string modelPath, int contrast, Mat p_mask)
{
HObject h_template;
MatC12HObject(mat, h_template);
if(p_mask.empty() == false) {
// imshow("mask", mask);
HObject ho_mask, ho_MaskRect;
MatC12HObject(p_mask, ho_mask);
HObject mask;
HTuple minGray = 1, maxGray = 255;
Threshold(ho_mask, &mask, minGray, maxGray);
ReduceDomain(h_template, mask, &h_template);
}
CreateShapeModel(h_template, 5, HTuple(0).TupleRad(), HTuple(360).TupleRad(),
0.0175, "auto", "ignore_color_polarity", contrast, "auto", &tempModelID);
// return ;
this->templateW = mat.cols;
this->templateH = mat.rows;
this->templateMat = mat.clone();
std::string iPath, mPath;
getTemplatePath(modelPath, iPath, mPath);
debugInfo("写入模板: " + iPath + "," + mPath);
WriteShapeModel(tempModelID, (mPath).c_str());
imwrite(iPath, mat);
}
void HalconTool::LoadTempate(string modelPath)
{
std::string iPath, mPath;
getTemplatePath(modelPath, iPath, mPath);
this->debugInfo("加载模版: " + iPath + "," + mPath);
this->templateMat = imread(iPath, IMREAD_GRAYSCALE);
this->templateW = templateMat.cols;
this->templateH = templateMat.rows;
ReadShapeModel((mPath).c_str(), &tempModelID);
this->debugInfo("加载模版: " + iPath + "," + mPath + "ok.");
}
void HalconTool::GetTemplateRes(cv::Mat &res)
{
HObject ho_ModelContours;
GetShapeModelContours(&ho_ModelContours, tempModelID, 1);
res = this->templateMat.clone();
cvtColor(res, res, COLOR_GRAY2BGR);
HTuple numbumber;
CountObj(ho_ModelContours, &numbumber);
cout << "contours count:" << numbumber.I() << endl;
for(int i = 1; i < numbumber.I(); i++) {
//遍历轮廓
HTuple hv_Number, hv_Row, hv_Column;
HObject Img;
SelectObj(ho_ModelContours, &Img, i);
GetContourXld(Img, &hv_Row, &hv_Column);
for (int i = 0; i < hv_Row.Length(); i++) {
cout << "i:" << i << endl;
int row = static_cast<int>(hv_Row[i].D());
int col = static_cast<int>(hv_Column[i].D());
// int add = 150;
// row += add;
// col += add;
// col -= 10;
// row -= 17;
cout << "row:" << row << ", col:" << col << endl;
// 确保行列坐标在模板图像的有效范围内
if (row >= 0 && row < res.rows && col >= 0 && col < res.cols) {
// 将该点绘制为红色(或其他颜色)
res.at<cv::Vec3b>(row, col)[0] = 0; // B
res.at<cv::Vec3b>(row, col)[1] = 0; // G
res.at<cv::Vec3b>(row, col)[2] = 255; // R
}
}
}
}
void HalconTool::getTemplatePath(std::string modelPath, string &imgPath, string &shmPath)
{
imgPath = modelPath + "/" + imgTempName;
shmPath = modelPath + "/" + modelName;
}
void HalconTool::HScaleImage(Mat &mat, int mult, int add, Mat &out)
{
HObject ho_Template, ho_ImageScaled;
MatC12HObject(mat, ho_Template);
ScaleImage(ho_Template, &ho_ImageScaled, mult, add);
HObject2MatC1(ho_ImageScaled, out);
}
void HalconTool::HFindShapeModel(cv::Mat &targetMat,
float &row, float &col, float &angle,
float &score, vector<vector<Point2f>> &resControlPoint) {
HFIND_SHAPE_PARAM_DEF
HFindShapeModel(targetMat, v_rows, v_cols, v_angle, v_score, resControlPoint, 1);
if(v_rows.size() >= 1) {
row = v_rows[0];
col = v_cols[0];
angle = (180 / PI * v_angle[0]);//弧度转角度
score = v_score[0];
}
}
void HalconTool::HFindShapeModel(cv::Mat &targetMat,
vector<float> &rows, vector<float> &col, vector<float> &angle, vector<float> &score,
vector<vector<Point2f>> &resControlPoint, int matchNums)
{
resControlPoint.clear();
HObject ho_TargetImg;
MatC12HObject(targetMat, ho_TargetImg);
// imwrite("HFindShapeModel1.jpg", targetMat);
// ReadImage(&ho_TargetImg, "grabMat2-2.jpg");
HTuple hv_Row1, hv_Column1, hv_Angle1, hv_Score1;
FindShapeModel(ho_TargetImg, tempModelID, HTuple(0).TupleRad(), HTuple(360).TupleRad(),
0.7, matchNums, 0.1, "none", 0, 0, &hv_Row1, &hv_Column1, &hv_Angle1, &hv_Score1);
cout << "row:" << hv_Row1.Length() << endl;
for(int i = 0; i < hv_Row1.Length(); i++) {
rows.push_back(hv_Row1[i].D());
col.push_back(hv_Column1[i].D());
angle.push_back(hv_Angle1[i].D());
score.push_back(hv_Score1[i].D());
}
if(hv_Row1.Length() <= 0) {
return ;
}
//拿到识别轮廓像素点
//hv_Color没用,Halcon里头生成的代码这么用的,回头整理一下
HTuple hv_Color;
hv_Color.Clear();
hv_Color[0] = "red";
hv_Color[1] = "green";
hv_Color[2] = "blue";
hv_Color[3] = "cyan";
hv_Color[4] = "magenta";
hv_Color[5] = "yellow";
vector<HObject> resContrus;
this->dev_display_shape_matching_results(tempModelID, hv_Color,
hv_Row1, hv_Column1, hv_Angle1, 1, 1, 0, resContrus);
for(HObject item : resContrus) {
HTuple hv_Number, hv_Row, hv_Column;
HObject selItem;
CountObj(item, &hv_Number);
//每一个轮廓
vector<Point2f> contrusItem;
for(int i = 1; i < hv_Number.L(); i++) {
SelectObj(item, &selItem, i);
GetContourXld(selItem, &hv_Row, &hv_Column);
// SetSystem("width", 1280);
// SetSystem("height", 1280);
// HTuple hv_WinA;
// OpenWindow(0, 0, 1280, 1280, 0, "visible", "" ,&hv_WinA);
// DispObj(selItem, hv_WinA);
// Sleep(1000);
// continue;
for(int y = 1; y < hv_Row.Length(); y++) {
double dRow = hv_Row[y].D();
double dCol = hv_Column[y].D();
Point2f pos;
pos.x = dCol;
pos.y = dRow;
contrusItem.push_back(pos);
}
}
resControlPoint.push_back(contrusItem);
}
}
void HalconTool::HObject2MatC1(HObject Hobj, Mat &img) {
ConvertImageType(Hobj, &Hobj, "byte");
HalconCpp::HString cType;
HalconCpp::HImage hImg(Hobj);
Hlong wid = 0;
Hlong hgt = 0;
void *ptr = hImg.GetImagePointer1(&cType, &wid, &hgt);
img.create(Size(wid, hgt), CV_8UC1);
unsigned char *pdata = static_cast<unsigned char *>(ptr);
memcpy(img.data, pdata, wid * hgt);
}
void HalconTool::HObject2MatC3(HObject Hobj, Mat &img) {
ConvertImageType(Hobj, &Hobj, "byte");
HTuple w, h;
GetImageSize(Hobj, &w, &h);
HalconCpp::HImage hImg(Hobj);
HalconCpp::HTuple pointerR, pointerG, pointerB;
hImg.GetImagePointer3(&pointerR, &pointerG, &pointerB, nullptr, &w, &h);
uchar* R = (uchar*)(pointerR.L());
uchar* G = (uchar*)(pointerG.L());
uchar* B = (uchar*)(pointerB.L());
img = cv::Mat::zeros(h, w, CV_8UC3);
for (int i = 0; i < h; ++i) {
uchar *p = img.ptr<uchar>(i);
for (int j = 0; j < w; ++j) {
p[3 * j] = B[i * w + j];
p[3 * j + 1] = G[i * w + j];
p[3 * j + 2] = R[i * w + j];
}
}
}
//单通道Mat转HObject
void HalconTool::MatC12HObject(Mat &mat, HObject &hObj) {
HalconCpp::GenImage1(&hObj, "byte", mat.cols, mat.rows, reinterpret_cast<Hlong>(mat.data));
}
void HalconTool::HObjectC12C3(HObject &c1Img, HObject &c3Img) {
HTuple tempW, tempH;
GetImageSize(c1Img, &tempW, &tempH);
HObject ho_R, ho_G, ho_B;
GenImageConst(&ho_R, "byte", tempW, tempH);
GenImageConst(&ho_G, "byte", tempW, tempH);
GenImageConst(&ho_B, "byte", tempW, tempH);
for(int y = 0; y < tempH; y++) {
for(int x = 0; x < tempW; x++) {
HTuple v;
GetGrayval(c1Img, y, x, &v);
SetGrayval(ho_R, y, x, v);
SetGrayval(ho_G, y, x, v);
SetGrayval(ho_B, y, x, v);
}
}
Compose3(ho_R, ho_G, ho_B, &c3Img);
}
void HalconTool::dev_display_shape_matching_results (HTuple hv_ModelID, HTuple hv_Color, HTuple hv_Row,
HTuple hv_Column, HTuple hv_Angle, HTuple hv_ScaleR, HTuple hv_ScaleC, HTuple hv_Model, vector<HObject> &resContrus)
{
// Local iconic variables
HObject ho_ModelContours, ho_ContoursAffinTrans;
// Local control variables
HTuple hv_NumMatches, hv_Index, hv_Match, hv_HomMat2DIdentity;
HTuple hv_HomMat2DScale, hv_HomMat2DRotate, hv_HomMat2DTranslate;
//This procedure displays the results of Shape-Based Matching.
//
hv_NumMatches = hv_Row.TupleLength();
if (0 != (hv_NumMatches>0))
{
if (0 != ((hv_ScaleR.TupleLength())==1))
{
TupleGenConst(hv_NumMatches, hv_ScaleR, &hv_ScaleR);
}
if (0 != ((hv_ScaleC.TupleLength())==1))
{
TupleGenConst(hv_NumMatches, hv_ScaleC, &hv_ScaleC);
}
if (0 != ((hv_Model.TupleLength())==0))
{
TupleGenConst(hv_NumMatches, 0, &hv_Model);
}
else if (0 != ((hv_Model.TupleLength())==1))
{
TupleGenConst(hv_NumMatches, hv_Model, &hv_Model);
}
{
HTuple end_val15 = (hv_ModelID.TupleLength())-1;
HTuple step_val15 = 1;
for (hv_Index=0; hv_Index.Continue(end_val15, step_val15); hv_Index += step_val15)
{
GetShapeModelContours(&ho_ModelContours, HTuple(hv_ModelID[hv_Index]), 1);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),HTuple(hv_Color[hv_Index%(hv_Color.TupleLength())]));
{
HTuple end_val18 = hv_NumMatches-1;
HTuple step_val18 = 1;
for (hv_Match=0; hv_Match.Continue(end_val18, step_val18); hv_Match += step_val18)
{
if (0 != (hv_Index==HTuple(hv_Model[hv_Match])))
{
HomMat2dIdentity(&hv_HomMat2DIdentity);
HomMat2dScale(hv_HomMat2DIdentity, HTuple(hv_ScaleR[hv_Match]), HTuple(hv_ScaleC[hv_Match]),
0, 0, &hv_HomMat2DScale);
HomMat2dRotate(hv_HomMat2DScale, HTuple(hv_Angle[hv_Match]), 0, 0, &hv_HomMat2DRotate);
HomMat2dTranslate(hv_HomMat2DRotate, HTuple(hv_Row[hv_Match]), HTuple(hv_Column[hv_Match]),
&hv_HomMat2DTranslate);
AffineTransContourXld(ho_ModelContours, &ho_ContoursAffinTrans, hv_HomMat2DTranslate);
resContrus.push_back(ho_ContoursAffinTrans);
// DispObj(ho_ContoursAffinTrans, );
// if (HDevWindowStack::IsOpen())
// DispObj(ho_ContoursAffinTrans, HDevWindowStack::GetActive());
}
}
}
}
}
}
}GetTemplateRes函数内,感觉GetContourXld后的坐标系不太对,获取到的行列有负数