void widget::on_pushButton_ImageProcessing_clicked()
{
// HTuple hv_Exception,hv_ErroCode;
// try
// {
// CountSeconds(&hv_S1);
//关闭当前窗口。
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());
//读取图片
ReadImage(&ho_Image,L"D://Data//实验图片");
//打开一个窗口并显示图像,窗口大小根据图像大小自动调整,并将窗口句柄赋值给变量WindowHandle。
dev_open_window_fit_image(ho_Image, 0, 0, 960, 1920, &hv_WindowHandle);
//设置窗口中显示的字体大小为16,字体类型为'mono',抗锯齿开启。
set_display_font(hv_WindowHandle, 16, "mono", "true", "false");
//设置图形绘制模式为'margin',即边缘绘制。
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(),"margin");
// //获取系统设置的存储空区域参数,并将其赋值给变量StoreEmptyRegion。
GetSystem("store_empty_region", &hv_StoreEmptyRegion);
// //设置系统设置的存储空区域参数为'true',即开启存储空区域功能。
SetSystem("store_empty_region", "true");
// //定义一个变量cm_per_pix,表示每像素对应的厘米数,这里设置为0.0373。
//hv_cm_per_pix = 0.0373;
// //定义一个变量TargetLength,表示目标长度,这里设置为55pixel。
hv_TargetLength = 55.0;
// //定义一个变量ToleranceHigh,表示高容忍度,这里设置为0.8。
hv_ToleranceHigh = 6;
// //定义一个变量ToleranceLow,表示低容忍度,这里设置为0.2
hv_ToleranceLow = 7;
// //定义一个变量LongTargetLength,表示目标长度,这里设置为115pixel。
hv_LongTargetLength = 115.0;
// //定义一个变量LongToleranceHigh,表示高容忍度,这里设置为0.8。
hv_LongToleranceHigh = 5;
// //定义一个变量LongToleranceLow,表示低容忍度,这里设置为0.2
hv_LongToleranceLow = 5;
// //一个整数类型的变量,表示接下来要读取的图像数量。
hv_NumImages = 10;
//for I := 1 to NumImages by 1
//保存一张新的图片图片名为Imageprocess.2.bmp
//read_image (Image, 'D:/Data/实际数量图片(正常2)')
//使用threshold算子进行局部自适应阈值分割17
Threshold(ho_Image, &ho_DivisionRegion, 0, 17);
//使用local_threshold算子进行局部自适应阈值分割4
//local_threshold (Image, DivisionRegion, 'adapted_std_deviation', 'dark', 'mask_size', 15)
//参数说明:
//ImageIn: 输入的单通道灰度图像
//ImageOut: 输出的二值图像(背景为0,前景为1)
//'adapted_std_deviation': 这是当前唯一支持
//'dark':表示使用暗通道方法确定局部阈值。
//'mask_size':表示用于计算局部阈值的像素邻域大小。这里设置为 15。
//膨胀处理
DilationRectangle1(ho_DivisionRegion, &ho_RegionDilation, 3, 3);
//将不相连的区域分开成若干个区域
Connection(ho_RegionDilation, &ho_ConnectedRegions);
//填充连通域
FillUp(ho_ConnectedRegions, &ho_RegionFillUp);
//形状选择宽度在30px-70px之间的区域
SelectShape(ho_RegionFillUp, &ho_Widths, "width", "and", 7, 120);
SelectShape(ho_Widths, &ho_Heights, "height", "and", 7, 120);
SelectShape(ho_Heights, &ho_SelectedRegions, "area", "and", 90, 99999);
//计算联通区面积
//select_shape ()
//去掉被图像边缘隔断的区域
Boundary(ho_Image, &ho_RegionBorder, "inner");
//找到有效区域与边界的交集,注意交集是多维,有可能存在空区域
Intersection(ho_SelectedRegions, ho_RegionBorder, &ho_RegionIntersection);
AreaCenter(ho_RegionIntersection, &hv_Area, &hv_Row1, &hv_Column1);
//如果交集面积为0,则该区域不与边界相交,反之则相交。[==]中的[]为元组处理,获取到的是索引
//用于根据对象的属性进行筛选的操作算子,用来基于区域(或对象)的面积属性来选择连通区域。
select_mask_obj(ho_SelectedRegions, &ho_ValidSticks, hv_Area.TupleEqualElem(0));
select_mask_obj(ho_SelectedRegions, &ho_StickAtBorder, hv_Area.TupleNotEqualElem(0));
//这个最小外接矩形是能够完全包裹住给定连通区域且具有最小面积的矩形,并且它可以是任意旋转角度。
//检查一下物体的大小* 最小外接矩形,判断是否合格Length1, Length2: 输出参数,分别表示最小外接矩形的两个边长,其中Length1 >= Length2
SmallestRectangle2(ho_ValidSticks, &hv_Row, &hv_Column, &hv_Phi, &hv_Length1,&hv_Length2);
//实际的像素大小,cm_per_pix是已经标定计算好的,*2是因为Length1为半径:: FishLength1 := Length1 * 2 * cm_per_pix
hv_FishLength1 = hv_Length1*2;
//判断是否合格,注意这里的优先级,+-优先级大于 >= 这些,实际不确定时就加小括号
// try {
hv_Good = (hv_FishLength1.TupleGreaterEqualElem(hv_TargetLength-hv_ToleranceLow)).TupleAnd(hv_FishLength1.TupleLessEqualElem(hv_TargetLength+hv_ToleranceHigh));
hv_LongGood = (hv_FishLength1.TupleGreaterEqualElem(hv_LongTargetLength-hv_LongToleranceLow)).TupleAnd(hv_FishLength1.TupleLessEqualElem(hv_LongTargetLength+hv_LongToleranceHigh));
hv_Bad = hv_Good.TupleNot();
// }
// catch (HalconCpp::HException &HDevExpDefaultException) {
// // 处理异常的代码块
// //std::cerr << "Exception caught: " << e.what() << std::endl;
// HDevExpDefaultException.ToHTuple(&hv_Exception);
// hv_ErroCode = ((const HTuple&)hv_Exception)[0];
// }
//
//显示结果
hv_RowGood = hv_Row.TupleSelectMask(hv_Good);
hv_ColumnGood = hv_Column.TupleSelectMask(hv_Good);
hv_RowBad = hv_Row.TupleSelectMask(hv_Bad);
hv_ColumnBad = hv_Column.TupleSelectMask(hv_Bad);
hv_RowLongGood = hv_Row.TupleSelectMask(hv_LongGood);
hv_ColumnLongGood = hv_Column.TupleSelectMask(hv_LongGood);
hv_FishLength1Good = hv_FishLength1.TupleSelectMask(hv_Good);
hv_FishLength1Bad = hv_FishLength1.TupleSelectMask(hv_Bad);
hv_FishLength1LongGood = hv_FishLength1.TupleSelectMask(hv_LongGood);
GenRectangle2(&ho_AllSticks, hv_Row, hv_Column, hv_Phi, hv_Length1, hv_Length2);
select_mask_obj(ho_AllSticks, &ho_GoodSticks, hv_Good);
select_mask_obj(ho_AllSticks, &ho_BadSticks, hv_Bad);
select_mask_obj(ho_AllSticks, &ho_LongGoodSticks, hv_LongGood);
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"white");
if (HDevWindowStack::IsOpen())
SetLineWidth(HDevWindowStack::GetActive(),1);
if (HDevWindowStack::IsOpen())
DispObj(ho_ValidSticks, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetLineWidth(HDevWindowStack::GetActive(),3);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"yellow");
if (HDevWindowStack::IsOpen())
DispObj(ho_StickAtBorder, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"green");
if (HDevWindowStack::IsOpen())
DispObj(ho_GoodSticks, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"red");
if (HDevWindowStack::IsOpen())
DispObj(ho_BadSticks, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"cadet blue");
if (HDevWindowStack::IsOpen())
DispObj(ho_LongGoodSticks, HDevWindowStack::GetActive());
//String := 'Target length: ' + TargetLength$'.1f' + ' cm'(源代码)改为显示像素点
hv_String = ("Target length: "+(hv_TargetLength.TupleString(".1f")))+"pixel";
hv_String[1] = (("Tolerance: -"+(hv_ToleranceLow.TupleString(".1f")))+"/+")+(hv_ToleranceHigh.TupleString(".1f"));
disp_message(hv_WindowHandle, hv_String, "window", 12, 12, "black", "true");
//disp_message (WindowHandle, 'OK', 'image', 80, ColumnGood - 10, 'green', 'false')
disp_message(hv_WindowHandle, (hv_FishLength1Good.TupleString(".1f"))+"pixel","image", hv_RowGood, hv_ColumnGood-28, "green", "false");
//disp_message (WindowHandle, 'Not OK', 'image', 80, ColumnBad - 30, 'red', 'false')
disp_message(hv_WindowHandle, (hv_FishLength1Bad.TupleString(".1f"))+"pixel","image", hv_RowBad, hv_ColumnBad-28, "blue", "false");
// if (I != NumImages)
disp_continue_message(hv_WindowHandle, "black", "true");
CountSeconds(&hv_S2);
hv_Time = hv_S2-hv_S1;
WriteString(hv_WindowHandle, ("运行时间是:"+hv_Time)+"s");
// stop ()
// endif
// endfor
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"red");
SetSystem("store_empty_region", hv_StoreEmptyRegion);
GenRegionPoints(&ho_BadSticks, hv_rot_x, hv_rot_y);
//htuple转string
int BadRowNumber = hv_RowBad.Length();
int BadColumnNumber = hv_ColumnBad.Length();
HTuple hv_BadLength;
TupleLength(hv_RowBad,&hv_BadLength);
cout << BadRowNumber << "," << BadColumnNumber << endl;
cout << hv_RowBad[BadRowNumber - 1].D() << "," << hv_ColumnBad[BadColumnNumber - 1].D() << endl;
cout << "Number of elements in hv_RowBad: " << hv_BadLength.I() << std::endl;
//储存执行坐标
struct Coord
{
double x;
double y;
};
vector<Coord>BadCoord;//创建坐标数组
for(int i = 0 ; i <= BadRowNumber - 1 ; i++)
{
for(int j = 0 ; j <= BadColumnNumber - 1 ; j++)
{
Coord coord;//实例化的坐标点
coord.x = hv_RowBad[i].D();
coord.y = hv_ColumnBad[j].D();
BadCoord.push_back(coord);//将坐标点添加到向量中
}
}
QString message ;
for(const auto& coord : BadCoord)
{
std::cout << "Coordinate: (" << coord.x << ", " << coord.y << ")" << std::endl;
// 将坐标信息转换为字符串并发送到串口
if (!message.isEmpty()) {
message.append(", "); // 在已有内容后添加分隔符
}
message.append(QString::number(coord.x)); // 将 x 值转换为字符串并添加到 message
message.append(",");
message.append(QString::number(coord.y)); // 将 y 值转换为字符串并添加到 message
// serialPort->write(message.toUtf8());
// ui->textBrowser_Send->insertPlainText(message);
}
serialPort->write(message.toUtf8());
ui->textBrowser_Send->insertPlainText(message);
//}
// catch (HalconCpp::HException &HDevExpDefaultException)
// {
// // 处理异常的代码块
// //std::cerr << "Exception caught: " << e.what() << std::endl;
// HDevExpDefaultException.ToHTuple(&hv_Exception);
// hv_ErroCode = ((const HTuple&)hv_Exception)[0];
// }
}
执行后程序中断:
调试执行出现以下错误: