最近来触碰一下halcon,一直以来作为ai算法工程师,虽然知道halcon,但是一直也没有用过
对于我们用户来说,halcon与opencv的差距主要在下面:
(1)halcon是闭源的,商业的软件,优点是算子丰富,应用成熟
(2)opencv是开源的,社区强大
我们只是使用者而已,很多公司也是有一个专门将halcon的功能替换为opencv的这么一个岗位,这样摆脱商业库的依赖。当然还有更牛逼的全部算子手写,不使用opencv。很明显我不是这种人!
那好,我们先来看我们的第一个例子吧:
这个例子是来源于:
明显是个2d测量类的例子,主要是测量孔洞的平均半径和方差半径。
Halcon代码如下:
read_image (Image, 'progres')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowID)
dev_set_color ('red')
gen_rectangle1 (Rectangle, 260, 90, 360, 350)
reduce_domain (Image, Rectangle, ImageReduced)
threshold (ImageReduced, Dark, 0, 150)
connection (Dark, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 100)
elliptic_axis (SelectedRegions, Ra, Rb, Phi)
area_center (SelectedRegions, Area, Row, Column)
dev_set_draw ('margin')
dev_display (Image)
* dev_set_colored (12)
dev_set_color ('green')
dev_display (SelectedRegions)
MeanRadius := sum(Ra) / |Ra|
VarianceRadius := sum(Ra * Ra - MeanRadius * MeanRadius) / (|Ra| - 1)
我们先来解读一下以上的代码:
1)read_image (Image, 'progres'):读取图像
2)get_image_size (Image, Width, Height):获取读入图像的宽和高
3)dev_close_window ():关闭窗口,放在这里也是为了关闭一些潜在的没有关闭的可视化窗口
4)dev_open_window (0, 0, Width, Height, 'white', WindowID):打开一个窗口
5)dev_set_color ('red'):设置颜色
6)gen_rectangle1 (Rectangle, 260, 90, 360, 350):生成一个矩形
7)reduce_domain(Image, Rectangle, ImageReduced): 通过reduce_domain确实能获得特定区域Region位置的图像,但是,reduce_domain是缩小一个图像的定义域,并不缩小图像的实际尺寸,即新图像ImageReduced尺寸大小并未发生变化。如果使用get_image_size来计算ImageReduced图像的尺寸,其尺寸和 原图Image一样。并且,包括一系列的domain算子,比如change_domain,均不改变图像矩阵的大小。
reduce_domain (Image, Rectangle, ImageReduced):可以理解为,获取Image图上Rectangle区域大小的图,这个小图就是返回给ImageReduced。为了减小处理的区域
8)threshold (ImageReduced, Dark, 0, 150):就是一个阈值分割,输入ImageReduced,输出
Dark。
9)connection (Dark, ConnectedRegions):连通域分析
10)select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 100):应该是根据面积和大小挑选。
11)elliptic_axis (SelectedRegions, Ra, Rb, Phi):
12)area_center (SelectedRegions, Area, Row, Column):
13)dev_set_draw ('margin'):
14)dev_display (Image):显示图像Image,这个是原图
15)dev_set_color ('green'):设置后面待显示的对象的颜色
16)dev_display (SelectedRegions):显示选择出来的区域,颜色就是绿色的
17)MeanRadius := sum(Ra) / |Ra|、VarianceRadius := sum(Ra * Ra - MeanRadius * MeanRadius) / (|Ra| - 1):计算出所需要的测量值
可以看到其中的图像变量有多个图,但注意这些都是变量,直接halcon自己在变量窗口中自己显示出来的。
5张图的前三张都可以双击后,在画布上显示,分别按照顺序是:
获得的dark,可以看到没经过连通域分析,这时还有右下角一大块干扰。
剩下这两个图像变量就无法在画布上显示了(这个我也不晓得,刚接触halcon)
Halcon C++或者Halcon C#是很频繁的用法,想要将halcon落地到真正的应用上,这个是必须的。
那么如何导出到c++呢?请看下面的做法!
导出代码如下:
///
// File generated by HDevelop for HALCON/C++ Version 21.11.0.0
// Non-ASCII strings in this file are encoded in local-8-bit encoding (cp936).
// Ensure that the interface encoding is set to locale encoding by calling
// SetHcppInterfaceStringEncodingIsUtf8(false) at the beginning of the program.
//
// Please note that non-ASCII characters in string constants are exported
// as octal codes in order to guarantee that the strings are correctly
// created on all systems, independent on any compiler settings.
//
// Source files with different encoding should not be mixed in one project.
///
#ifndef __APPLE__
# include "HalconCpp.h"
# include "HDevThread.h"
#else
# ifndef HC_LARGE_IMAGES
# include
# include
# include
# else
# include
# include
# include
# endif
# include
# include
#endif
using namespace HalconCpp;
#ifndef NO_EXPORT_MAIN
// Main procedure
void action()
{
// Local iconic variables
HObject ho_Image, ho_Rectangle, ho_ImageReduced;
HObject ho_Dark, ho_ConnectedRegions, ho_SelectedRegions;
// Local control variables
HTuple hv_Width, hv_Height, hv_WindowID, hv_Ra;
HTuple hv_Rb, hv_Phi, hv_Area, hv_Row, hv_Column, hv_MeanRadius;
HTuple hv_VarianceRadius;
ReadImage(&ho_Image, "progres");
GetImageSize(ho_Image, &hv_Width, &hv_Height);
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());
SetWindowAttr("background_color","white");
OpenWindow(0,0,hv_Width,hv_Height,0,"visible","",&hv_WindowID);
HDevWindowStack::Push(hv_WindowID);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"red");
GenRectangle1(&ho_Rectangle, 260, 90, 360, 350);
ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
Threshold(ho_ImageReduced, &ho_Dark, 0, 150);
Connection(ho_Dark, &ho_ConnectedRegions);
SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 10, 100);
EllipticAxis(ho_SelectedRegions, &hv_Ra, &hv_Rb, &hv_Phi);
AreaCenter(ho_SelectedRegions, &hv_Area, &hv_Row, &hv_Column);
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(),"margin");
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
//dev_set_colored (12)
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(),"green");
if (HDevWindowStack::IsOpen())
DispObj(ho_SelectedRegions, HDevWindowStack::GetActive());
hv_MeanRadius = (hv_Ra.TupleSum())/(hv_Ra.TupleLength());
hv_VarianceRadius = (((hv_Ra*hv_Ra)-(hv_MeanRadius*hv_MeanRadius)).TupleSum())/((hv_Ra.TupleLength())-1);
}
#ifndef NO_EXPORT_APP_MAIN
#ifdef __APPLE__
// On OS X systems, we must have a CFRunLoop running on the main thread in
// order for the HALCON graphics operators to work correctly, and run the
// action function in a separate thread. A CFRunLoopTimer is used to make sure
// the action function is not called before the CFRunLoop is running.
// Note that starting with macOS 10.12, the run loop may be stopped when a
// window is closed, so we need to put the call to CFRunLoopRun() into a loop
// of its own.
static HMutex* sStartMutex;
static H_pthread_t sActionThread;
static bool sTerminate = false;
static void timer_callback(CFRunLoopTimerRef timer, void *info)
{
sStartMutex->UnlockMutex();
}
static Herror apple_action(void **parameters)
{
// Wait until the timer has fired to start processing.
sStartMutex->LockMutex();
sStartMutex->UnlockMutex();
try
{
action();
}
catch (HException &exception)
{
fprintf(stderr," Error #%u in %s: %s\n", exception.ErrorCode(),
exception.ProcName().TextA(),
exception.ErrorMessage().TextA());
}
// Tell the main thread to terminate itself.
sStartMutex->LockMutex();
sTerminate = true;
sStartMutex->UnlockMutex();
CFRunLoopStop(CFRunLoopGetMain());
return H_MSG_OK;
}
static int apple_main(int argc, char *argv[])
{
Herror error;
CFRunLoopTimerRef Timer;
CFRunLoopTimerContext TimerContext = { 0, 0, 0, 0, 0 };
sStartMutex = new HMutex("type","sleep");
sStartMutex->LockMutex();
error = HpThreadHandleAlloc(&sActionThread);
if (H_MSG_OK != error)
{
fprintf(stderr,"HpThreadHandleAlloc failed: %d\n", error);
exit(1);
}
error = HpThreadCreate(sActionThread,0,apple_action);
if (H_MSG_OK != error)
{
fprintf(stderr,"HpThreadCreate failed: %d\n", error);
exit(1);
}
Timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent(),0,0,0,
timer_callback,&TimerContext);
if (!Timer)
{
fprintf(stderr,"CFRunLoopTimerCreate failed\n");
exit(1);
}
CFRunLoopAddTimer(CFRunLoopGetCurrent(),Timer,kCFRunLoopCommonModes);
for (;;)
{
bool terminate;
CFRunLoopRun();
sStartMutex->LockMutex();
terminate = sTerminate;
sStartMutex->UnlockMutex();
if (terminate)
break;
}
CFRunLoopRemoveTimer(CFRunLoopGetCurrent(),Timer,kCFRunLoopCommonModes);
CFRelease(Timer);
error = HpThreadHandleFree(sActionThread);
if (H_MSG_OK != error)
{
fprintf(stderr,"HpThreadHandleFree failed: %d\n", error);
exit(1);
}
delete sStartMutex;
return 0;
}
#endif
int main(int argc, char *argv[])
{
int ret = 0;
try
{
#if defined(_WIN32)
SetSystem("use_window_thread", "true");
#endif
// file was stored with local-8-bit encoding
// -> set the interface encoding accordingly
SetHcppInterfaceStringEncodingIsUtf8(false);
// Default settings used in HDevelop (can be omitted)
SetSystem("width", 512);
SetSystem("height", 512);
#ifndef __APPLE__
action();
#else
ret = apple_main(argc,argv);
#endif
}
catch (HException &exception)
{
fprintf(stderr," Error #%u in %s: %s\n", exception.ErrorCode(),
exception.ProcName().TextA(),
exception.ErrorMessage().TextA());
ret = 1;
}
return ret;
}
#endif
#endif
我们在vs2019中配置运行一下:
halcon.props:
E:\setup_app\opencv453\build\include;../../3dparty/halcon_2111/include;../../3dparty/halcon_2111/include/halconcpp;../../3dparty/halcon_2111/include/hlib;../../3dparty/halcon_2111/include/hdevengine;../../3dparty/halcon_2111/include/hclib;../../3dparty/halcon_2111/include/halconc;../../3dparty/glog/include;$(IncludePath)
E:\setup_app\opencv453\build\x64\vc14\lib;../../3dparty/halcon_2111/x64-win64/lib;../../3dparty/glog/lib;$(LibraryPath)
E:\setup_app\opencv453\build\x64\vc14\bin;$(ExecutablePath)
opencv_world453d.lib;
%(AdditionalDependencies)
opencv_world453.lib;
glog.lib;
halcon.lib;
halconc.lib;
halconcpp.lib;
halconcppxl.lib;
halconcxl.lib;
halconxl.lib;
hdevenginecpp.lib;
hdevenginecppxl.lib;
libiomp5md.lib;
%(AdditionalDependencies)
为了让我们的显示窗口不要一闪而过,因为我们需要添加"等待函数":
可以看到,要加等待函数,其次要想获得halcon的变量的值,必须前面使用double等数值类型,才可以看到,否则是无法看到具体数值的,最后我这里先给出疑问,如何像Halcon中那样可以看到图像变量,并进行可视化呢?这个后面再回过头来解决!
我一开始也是不明白导出的那么多东西,是如何精简。后面根据使用过的人说一般是用不到的直接删掉。
因此我小心删除,精简后的代码如下:
#include "HalconCpp.h"
#include
using namespace HalconCpp;
// Main procedure
void action()
{
// Local iconic variables
HObject ho_Image, ho_Rectangle, ho_ImageReduced;
HObject ho_Dark, ho_ConnectedRegions, ho_SelectedRegions;
// Local control variables
HTuple hv_Width, hv_Height, hv_WindowID, hv_Ra;
HTuple hv_Rb, hv_Phi, hv_Area, hv_Row, hv_Column, hv_MeanRadius;
HTuple hv_VarianceRadius;
ReadImage(&ho_Image, "progres");
GetImageSize(ho_Image, &hv_Width, &hv_Height);
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());
SetWindowAttr("background_color", "white");
OpenWindow(0, 0, hv_Width, hv_Height, 0, "visible", "", &hv_WindowID);
HDevWindowStack::Push(hv_WindowID);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "red");
GenRectangle1(&ho_Rectangle, 260, 90, 360, 350);
ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
Threshold(ho_ImageReduced, &ho_Dark, 0, 150);
Connection(ho_Dark, &ho_ConnectedRegions);
SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 10, 100);
EllipticAxis(ho_SelectedRegions, &hv_Ra, &hv_Rb, &hv_Phi);
AreaCenter(ho_SelectedRegions, &hv_Area, &hv_Row, &hv_Column);
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(), "margin");
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
WaitSeconds(5.0);
//dev_set_colored (12)
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "green");
if (HDevWindowStack::IsOpen())
DispObj(ho_SelectedRegions, HDevWindowStack::GetActive());
WaitSeconds(5.0);
hv_MeanRadius = (hv_Ra.TupleSum()) / (hv_Ra.TupleLength());
hv_VarianceRadius = (((hv_Ra * hv_Ra) - (hv_MeanRadius * hv_MeanRadius)).TupleSum()) / ((hv_Ra.TupleLength()) - 1);
std::cout << "hv_MeanRadius平均半径:" << double(hv_MeanRadius) << std::endl;
std::cout << "hv_VarianceRadius方差半径:" << double(hv_VarianceRadius) << std::endl;
}
int main(int argc, char* argv[])
{
int ret = 0;
try
{
// file was stored with local-8-bit encoding
// -> set the interface encoding accordingly
SetHcppInterfaceStringEncodingIsUtf8(false);
// Default settings used in HDevelop (can be omitted)
SetSystem("width", 512);
SetSystem("height", 512);
action();
}
catch (HException& exception)
{
fprintf(stderr, " Error #%u in %s: %s\n", exception.ErrorCode(),
exception.ProcName().TextA(),
exception.ErrorMessage().TextA());
ret = 1;
}
return ret;
}
配置运行还是跟前面的是一样的。
那么我们做下代码解析吧
(1)先看主函数
整体上是一个异常捕捉try-catch结构,其中 SetHcppInterfaceStringEncodingIsUtf8(false);这个就是从Halcon v18.x开始支持中文路径,但是要事先调用 SetHcppInterfaceStringEncodingIsUtf8(false);算子来进行设置支持中文解析。
halcon 默认最大显示为512*512
(2)进入action函数
这个action函数实际才是我们的最重要的算法实现部分!
// Main procedure
void action()
{
// Local iconic variables
HObject ho_Image, ho_Rectangle, ho_ImageReduced;
HObject ho_Dark, ho_ConnectedRegions, ho_SelectedRegions;
// Local control variables
HTuple hv_Width, hv_Height, hv_WindowID, hv_Ra;
HTuple hv_Rb, hv_Phi, hv_Area, hv_Row, hv_Column, hv_MeanRadius;
HTuple hv_VarianceRadius;
ReadImage(&ho_Image, "progres");
GetImageSize(ho_Image, &hv_Width, &hv_Height);
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());
SetWindowAttr("background_color", "white");
OpenWindow(0, 0, hv_Width, hv_Height, 0, "visible", "", &hv_WindowID);
HDevWindowStack::Push(hv_WindowID);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "red");
GenRectangle1(&ho_Rectangle, 260, 90, 360, 350);
ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
Threshold(ho_ImageReduced, &ho_Dark, 0, 150);
Connection(ho_Dark, &ho_ConnectedRegions);
SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 10, 100);
EllipticAxis(ho_SelectedRegions, &hv_Ra, &hv_Rb, &hv_Phi);
AreaCenter(ho_SelectedRegions, &hv_Area, &hv_Row, &hv_Column);
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(), "margin");
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
WaitSeconds(5.0);
//dev_set_colored (12)
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "green");
if (HDevWindowStack::IsOpen())
DispObj(ho_SelectedRegions, HDevWindowStack::GetActive());
WaitSeconds(5.0);
hv_MeanRadius = (hv_Ra.TupleSum()) / (hv_Ra.TupleLength());
hv_VarianceRadius = (((hv_Ra * hv_Ra) - (hv_MeanRadius * hv_MeanRadius)).TupleSum()) / ((hv_Ra.TupleLength()) - 1);
std::cout << "hv_MeanRadius平均半径:" << double(hv_MeanRadius) << std::endl;
std::cout << "hv_VarianceRadius方差半径:" << double(hv_VarianceRadius) << std::endl;
}
局部符号变量。
局部控制变量。主要是一些属性的表达,如图的宽高、半径、弧长等。
那么我们这里可以看到HObject和HTuple这两个类,那为什么分别用这两个类来声明变量呢?
答:HALCON里面有很多数据类型,但是通过的导出向导工具导出后,就剩下两种数据类型:Hobject HTuple。一个是图像 一个是数据。
头文件有定义这两个C++类:
C:\Program Files\MVTec\HALCON-20.11-Progress\include\halconcpp\HObject.h
C:\Program Files\MVTec\HALCON-20.11-Progress\include\halconcpp\HTuple.h
HObject:
// Represents an instance of an iconic object(-array). Base class for images, regions and XLDs
class LIntExport HObject : public HObjectBase
{
public:
// Create an uninitialized instance
HObject():HObjectBase() {}
// Copy constructor
HObject(const HObject& source) : HObjectBase(source) {}
// Create HObject from object id. For copy=false takes
// over management of input key. Type of key must match!
explicit HObject(Hkey key, bool copy=true);
// Access of object tuple element
const HObject operator [] (Hlong index) const;
// Deep copy of all data represented by this object instance
HObject Clone() const;
/***************************************************************************
* Operators *
***************************************************************************/
// Calculate the difference of two object tuples.
HObject ObjDiff(const HObject& ObjectsSub) const;
// Convert an "integer number" into an iconic object.
void IntegerToObj(const HTuple& SurrogateTuple);
// Convert an "integer number" into an iconic object.
void IntegerToObj(void* SurrogateTuple);
// Convert an iconic object into an "integer number."
HTuple ObjToInteger(Hlong Index, Hlong Number) const;
// Copy an iconic object in the HALCON database.
HObject CopyObj(Hlong Index, Hlong NumObj) const;
// Concatenate two iconic object tuples.
HObject ConcatObj(const HObject& Objects2) const;
// Select objects from an object tuple.
HObject SelectObj(const HTuple& Index) const;
// Select objects from an object tuple.
HObject SelectObj(Hlong Index) const;
// Compare iconic objects regarding equality.
Hlong CompareObj(const HObject& Objects2, const HTuple& Epsilon) const;
// Compare iconic objects regarding equality.
Hlong CompareObj(const HObject& Objects2, double Epsilon) const;
// Compare image objects regarding equality.
Hlong TestEqualObj(const HObject& Objects2) const;
// Number of objects in a tuple.
Hlong CountObj() const;
// Informations about the components of an image object.
HTuple GetChannelInfo(const HString& Request, const HTuple& Channel) const;
// Informations about the components of an image object.
HString GetChannelInfo(const HString& Request, Hlong Channel) const;
// Informations about the components of an image object.
HString GetChannelInfo(const char* Request, Hlong Channel) const;
#ifdef _WIN32
// Informations about the components of an image object.
HString GetChannelInfo(const wchar_t* Request, Hlong Channel) const;
#endif
// Name of the class of an image object.
HTuple GetObjClass() const;
// Create an empty object tuple.
void GenEmptyObj();
// Displays image objects (image, region, XLD).
void DispObj(const HWindow& WindowHandle) const;
// Read an iconic object.
void ReadObject(const HString& FileName);
// Read an iconic object.
void ReadObject(const char* FileName);
#ifdef _WIN32
// Read an iconic object.
void ReadObject(const wchar_t* FileName);
#endif
// Write an iconic object.
void WriteObject(const HString& FileName) const;
// Write an iconic object.
void WriteObject(const char* FileName) const;
#ifdef _WIN32
// Write an iconic object.
void WriteObject(const wchar_t* FileName) const;
#endif
// Deserialize a serialized iconic object.
void DeserializeObject(const HSerializedItem& SerializedItemHandle);
// Serialize an iconic object.
HSerializedItem SerializeObject() const;
// Insert objects into an iconic object tuple.
HObject InsertObj(const HObject& ObjectsInsert, Hlong Index) const;
// Remove objects from an iconic object tuple.
HObject RemoveObj(const HTuple& Index) const;
// Remove objects from an iconic object tuple.
HObject RemoveObj(Hlong Index) const;
// Replaces one or more elements of an iconic object tuple.
HObject ReplaceObj(const HObject& ObjectsReplace, const HTuple& Index) const;
// Replaces one or more elements of an iconic object tuple.
HObject ReplaceObj(const HObject& ObjectsReplace, Hlong Index) const;
private:
// Verify matching semantic type ('object')!
void AssertObjectClass();
};
红色框中的api:
1)ReadImage:读取图片,同Hdev
2)GetImageSize:获取图片的宽高,同Hdev
其余的api也是同Hdev中的一样功能。
这里要说明一下SelectShape、EllipticAxis和AreaCenter:
3)select_shape:
参考:Halcon 算子 select_shape_郑建广视觉的博客-CSDN博客_selectshape
select_shape(select_shape(Regions : SelectedRegions : Features, Operation, Min, Max : )):算子select_shape根据形状特征选择区域,对于输入的每个区域,将计算指定的特征根据参数(features)。如果每个(Operation = 'and')或至少一个(Operation = 'or')的计算特性在默认限制(Min,Max)内,该区域将被输出。输入参数关系符('and', 'or')如果features只是用一种特性那么此参数没有意义。
Features的值:'area':区域的面积、'row':中心的行坐标、'column':中心的列坐标、'width':区域宽度(平行于坐标轴)、'height':区域的高度(平行于坐标轴)、'row1':区域左上角的行坐标、'circularity':和圆的相似度、'compactness':密度、'contlength':轮廓的总长度、'convexity':凸度、'rectangularity':类矩形因子、ra':主半径的等效椭圆、'rb':次半径的等效椭圆、'phi':和X轴的夹角、'anisometry:'等距、'bulkiness:'蓬松性、'dist_mean':从区域边界到区域中心的平均距离。海鸥很多。。。。
4)EllipticAxis:
参考:halcon-elliptic_axis计算区域的等效椭圆数据 - 天子骄龙 - 博客园
elliptic_axis (Region, Ra, Rb, Phi) *作用:计算区域的等效椭圆数据 *参数1:输入区域 *参数2:输出主半径 *参数3:输出次半径 *参数4:输出主半径和X轴的夹角(以弧度为单位 - pi / 2 < Phi && Phi <= pi / 2) *计算与输入区域具有相同方向和相同宽高比的椭圆的半径Ra和Rb以及方向Phi,多个输入区域可以作为数组传递
5)AreaCenter:
参考:https://www.cnblogs.com/liming19680104/p/15938000.html
area_center (Region, Area, Row, Column) *返回区域的面积和中心位置 *参数1:输入对象,即被测区域或图像 *参数2:输出变量,即被测区域的面积 *参数3:输出变量,即被测区域中心的行索引 *参数4:输出变量,即被测区域中心的列索引
1、halcon readimage不支持中文路径?_利白的博客-CSDN博客_halcon write_image 中文路径
2、halcon C++编程 第17讲 C++窗口函数(tcy)_tcy23456的博客-CSDN博客_dev_open_window
3、Halcon之可视化_yangyang_z的博客-CSDN博客_halcon中dump-window
4、HALCON 21.11:深度学习笔记---模型(8)_机器视觉001的博客-CSDN博客
5、b站上的
6、 Halcon学习--鱼棒长度测量--被测物体显示不全--去除方法_枫呱呱的博客-CSDN博客_halcon图像显示不全
7、Halcon之HALCON/C++ 接口的基础知识_yangyang_z的博客-CSDN博客_halcon c++
8、Halcon导出的C#代码的调用及讨论_HDevelop的c#dll-C#文档类资源-CSDN下载
9、Halcon的C++教程_爱上解放晚晚的博客-CSDN博客
10、halcon c++版本窗口不显示图_Angaoun的博客-CSDN博客_halcon c++代码不显示窗口
11、C++中显示Halcon窗口(2D&3D)_爱吃橙子的哈士奇的博客-CSDN博客_visualize_object_model_3d
12、halcon多目标模板匹配示例_halcon多模板匹配,halcon多模板匹配-C++文档类资源-CSDN下载
13、https://wang520.blog.csdn.net/article/details/108875243?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-108875243-blog-122517477.pc_relevant_aa2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-108875243-blog-122517477.pc_relevant_aa2&utm_relevant_index=6
14、VS2019配置Halcon的c++环境傻瓜式教程_asd_sz的博客-CSDN博客_vs2019配置halcon
15、Halcon缺陷检测实例转OpenCV实现(二) PCB印刷缺陷检测_51CTO博客_Halcon缺陷检测
16、2.2超人视觉初级班模板匹配(基于灰度)实战第二讲_哔哩哔哩_bilibili
17、VS2019配置Halcon的c++环境傻瓜式教程_asd_sz的博客-CSDN博客_vs2019配置halcon
18、Halcon学习(四) 导出C++代码,在VS2010下编译_zxucver的博客-CSDN博客_halcon20.11导出c++
19、HDevelop图形窗口操作(下)-工业视觉/halcon-少有人走的路
20、halcon开发必读 - NLazyo - 博客园
21、转HDevWindowStack详解 - 腾讯云开发者社区-腾讯云
22、机器学习 - 机器视觉工具学习---halcon - 个人文章 - SegmentFault 思否
23、Halcon+C#教程加载并显示图像-代码狗
24、Halcon HDEVELOP 工程导出集成到 C++ 应用程序 - 又见苍岚
25、halcon能导出python代码吗,或者其他能用python的途径都可 - Halcon技术 Halcon视觉技术网
26、Visual Studio 安装 Halcon Variable Inspect 插件可视化调试 Halcon 代码 - 又见苍岚
27\、halcon学习笔记(8)——QT显示halcon处理的图像和结果
28、Halcon常用的画ROI区域的生成保存读取_Johngo学长
29、HDevelop图形窗口操作(下)-工业视觉/halcon-少有人走的路
30、halcon 如何打开窗口,修改窗口,限制窗口_Regect的博客-CSDN博客_打开halcon窗口
31、halcon-dev_open_window打开新的图形窗口 - 天子骄龙 - 博客园
32、halcon学习笔记-报错-无法打开文件halcon.lib_超爱嵌入式的博客-CSDN博客
33、halcon学习网
34、按F1,可以搜索所有算子,每个算子的右上角,都分别有该算子原生的Hdev、c#、c++、python、c语言的接口形式和用法!一般的做法都是使用hdev语言写完,直接转c++或者c#
35、关于Halcon C++常用的两种数据结构Hobject和HTuple-阿里云开发者社区
36、Halcon 算子 select_shape_郑建广视觉的博客-CSDN博客_selectshape
37、halcon-area_center返回区域的面积和中心位置 - 天子骄龙 - 博客园