Halcon笔记1

news2024/11/28 6:37:16

一、前言

最近来触碰一下halcon,一直以来作为ai算法工程师,虽然知道halcon,但是一直也没有用过

对于我们用户来说,halcon与opencv的差距主要在下面:

(1)halcon是闭源的,商业的软件,优点是算子丰富,应用成熟

(2)opencv是开源的,社区强大

我们只是使用者而已,很多公司也是有一个专门将halcon的功能替换为opencv的这么一个岗位,这样摆脱商业库的依赖。当然还有更牛逼的全部算子手写,不使用opencv。很明显我不是这种人!

二、Halcon例子实操

那好,我们先来看我们的第一个例子吧:

这个例子是来源于:

 明显是个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) 

三、导出到C++

Halcon C++或者Halcon C#是很频繁的用法,想要将halcon落地到真正的应用上,这个是必须的。

那么如何导出到c++呢?请看下面的做法!

3.1、选择界面,文件-》导出语言...

导出代码如下:

///
// 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 <HALCONCpp/HalconCpp.h>
#    include <HALCONCpp/HDevThread.h>
#    include <HALCON/HpThread.h>
#  else
#    include <HALCONCppxl/HalconCpp.h>
#    include <HALCONCppxl/HDevThread.h>
#    include <HALCONxl/HpThread.h>
#  endif
#  include <stdio.h>
#  include <CoreFoundation/CFRunLoop.h>
#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


3.2、vs中运行

我们在vs2019中配置运行一下:

halcon.props:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
        <IncludePath>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)</IncludePath>

        <LibraryPath Condition="'$(Platform)'=='X64'">E:\setup_app\opencv453\build\x64\vc14\lib;../../3dparty/halcon_2111/x64-win64/lib;../../3dparty/glog/lib;$(LibraryPath)</LibraryPath>
        <ExecutablePath Condition="'$(Platform)'=='X64'">E:\setup_app\opencv453\build\x64\vc14\bin;$(ExecutablePath)</ExecutablePath>


  </PropertyGroup>
  <ItemDefinitionGroup>
        <Link Condition="'$(Configuration)'=='Debug'">
          <AdditionalDependencies>
			  opencv_world453d.lib;
			%(AdditionalDependencies)</AdditionalDependencies>
        </Link>
        <Link Condition="'$(Configuration)'=='Release'">
          <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)</AdditionalDependencies>
        </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
</Project>

 

为了让我们的显示窗口不要一闪而过,因为我们需要添加"等待函数":

 

注意:这个还需要一个附加库目录,否则会报错!

可以看到,要加等待函数,其次要想获得halcon的变量的值,必须前面使用double等数值类型,才可以看到,否则是无法看到具体数值的,最后我这里先给出疑问,如何像Halcon中那样可以看到图像变量,并进行可视化呢?这个后面再回过头来解决!

3.3、精简原始导出的代码,并做代码解析

我一开始也是不明白导出的那么多东西,是如何精简。后面根据使用过的人说一般是用不到的直接删掉。

因此我小心删除,精简后的代码如下:


#include "HalconCpp.h"
#include <stdio.h>



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返回区域的面积和中心位置 - 天子骄龙 - 博客园 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142882.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ATJ2158 LRADC的使用

LRADCLRADC对应引脚LRADC采样电压范围及位数使用LRADC涉及到的驱动文件如何使用不同的LRADC通道LRADC对应引脚 LRADC对应引脚备注LRACDC1WIO0/WIO1LRACDC2GPIO8/GPIO20LRACDC3GPIO9/GPIO21LRACDC4GPIO35LRACDC5GPIO5LRACDC6无没有找到相应的引脚LRACDC7GPIO63 LRADC采样电压范…

剑指 Offer 22. 链表中倒数第k个节点

剑指 Offer 22. 链表中倒数第k个节点 题目 输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表的尾节点是倒数第1个节点。 例如&#xff0c;一个链表有 6 个节点&#xff0c;从头节点开始&#xff0…

基于R的Bilibili视频数据建模及分析——聚类分析篇

基于R的Bilibili视频数据建模及分析——聚类分析篇 文章目录基于R的Bilibili视频数据建模及分析——聚类分析篇0、写在前面1、数据分析1.1 聚类分析1.2 聚类统计1.3 系统聚类1.4 Kmeans与主成分分析2、参考资料0、写在前面 实验环境 Python版本&#xff1a;Python3.9Pycharm版本…

python打包windows服务 开机自启动守护进程

自启动方法一&#xff1a;系统自启动设置python程序开机自启动1、创建一个xxx.bat文件&#xff0c;右键编辑2、在xxx.bat文件里面写入以下内容后保存&#xff1a;&#xff08;可以按照如下流程自己去cmd中测试一下&#xff09;d: #如果需要开机自启动的python程序在c盘&#xf…

Typora插图免费上传云端教程(太香了)

1、前言 我们平时在使用Typora时&#xff0c;文档中的图片一般是保存在本地&#xff0c;很方便&#xff0c;但是有些场景也有问题&#xff0c;比如我全部拷贝到有道云笔记中或者全部拷贝到CSDN中去发布时&#xff0c;你会发现&#xff0c;所有图片都无法预览了&#xff0c;此时…

不要为了“分库分表”而“分库分表”

数据库瓶颈 分库分表 分库分表工具 分库分表带来的问题 什么时候考虑分库分表 数据库瓶颈 不管是IO瓶颈还是CPU瓶颈&#xff0c;最终都会导致数据库的活跃连接数增加&#xff0c;进而逼近甚至达到数据库可承载的活跃连接数的阈值。在业务service来看&#xff0c; 就是可用…

解析HTTP请求报文(GET、POST)

目的&#xff1a; 一个WEB服务器需要解析客户端&#xff08;浏览器&#xff09;发来的请求&#xff0c;两种常见的请求方式是GET和POST。 GET的请求格式&#xff1a; GET请求没有请求体只有请求头GET请求的请求参数放在URL后加上一个"?"的后面&#xff0c;参数以…

时序图文献精度——1.2018-KDD-Embedding Temporal Network via Neighborhood Formation

Embedding Temporal Network via Neighborhood Formation Abstract 作者发现&#xff0c;在现有的研究中&#xff0c;以节点间顺序交互事件为特征的网络的完整时间形成过程还很少被建模&#xff0c;在这边文章中&#xff0c;作者引入邻域形成序列的概念来描述节点的演化&…

第四篇 - 对象的深层劫持

一&#xff0c;前言 上篇&#xff0c;主要介绍了在 Vue 的数据初始化流程中&#xff0c;对象属性的单层劫持是如何实现的 回顾一下&#xff0c;主要涉及以下几个核心点&#xff1a; data 为函数和对象的处理&#xff0c;及当 data 为函数时的 this 指向问题Observer 类&…

一文弄清楚vue中的computed和methods

1.实现业务我们现在需要实现一个业务&#xff0c;就是我们有一个输入框&#xff0c;之后我们修改输入框的值&#xff0c;就在此时输入框的值会呈现到页面中的h1标签上去2.利用Vue中的插值语法实现业务2.1什么是插值语法&#xff1f;插值语法就是vue中用来存放预留值得方法&…

【前端】CSS盒子模型

五、盒子模型 1.1盒子模型的介绍 盒子的概念 页面中的每一个标签&#xff0c;都可看做是一个“盒子”&#xff0c;通过盒子的视角方便的进行布局浏览器在渲染&#xff08;显示&#xff09;网页时&#xff0c;会奖网页中的元素看作是一个个的矩形区域&#xff0c;我们也形象地…

<Python的函数(1)>——《Python》

目录 1. 函数 2. 语法格式 2.1 创建函数/定义函数 ​2.2 调用函数/使用函数 3. 函数参数 4. 函数返回值 5. 变量作用域 后记&#xff1a;●由于作者水平有限&#xff0c;文章难免存在谬误之处&#xff0c;敬请读者斧正&#xff0c;俚语成篇&#xff0c;恳望指教&…

Android input 事件分发 -- inputReader

inputReaderinputReaderinputReader 这个章节主要是围绕inputReader 、inputReaderThread进行的&#xff0c;老规矩先上时序图通过前面我们已经知道了InputReader和InputReaderThread都是在InputManager的构造函数里面new出来的&#xff0c;然后InputReaderThread的启动是在Sys…

图文详解:内存总是不够,我靠HBase说服了Leader为新项目保驾护航

最近在工作中用到了 Hbase 这个数据库&#xff0c;也顺便做了关于 Hbase 的知识记录来分享给大家。其实 Hbase的内容体系真的很多很多&#xff0c;这里介绍的是小羽认为在工作中会用到的一些技术点&#xff0c;希望可以帮助到大家。 可以这么说互联网都是建立在形形色色的数据…

剑指offer----C语言版----第十天

目录 1. 二进制中 1 的个数 1.1 题目描述 1.2 可能引起错误的解法 1.3 常规解法 1.4 思路优化 1. 二进制中 1 的个数 原题链接: 剑指 Offer 15. 二进制中1的个数 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/er-jin-zhi-zhong-1de-ge-shu-lcof…

电路方案分析(十五)符合 EMC 标准的汽车制动灯和尾灯设计方案

符合 EMC 标准的汽车制动灯和尾灯设计方案 tips&#xff1a;TI设计方案参考分析&#xff1a;TI Designs&#xff1a;TIDA-01374 1.系统描述 1.1关键参数 2.系统概述 2.1系统框图 2.2关键元器件 3.设计原理 3.1双重亮度设计 3.2 电荷泵设计 3.4 LED故障设计 3.3 MOSFET驱动电…

LeetCode Hot 100 笔记

文章目录链表21. 合并两个有序链表栈20. 有效的括号Java栈链表 链表的题目一般都不太难&#xff0c;画图&#xff0c;别怕麻烦 21. 合并两个有序链表 解法一&#xff1a;迭代 用一个指针cur跟踪当前节点&#xff0c;每次从list1和list2中选取小的节点&#xff0c;链接起来建…

什么是轻量化,轻量化模型is all your need hhh

其实学了几个小月&#xff0c;我们肯定知道&#xff0c;MLP有多deeper &#xff0c;卷积层有多少层呀 抑或是Transformer架构&#xff0c;大量的参数&#xff0c;只能用huge 来描述&#xff0c; 可实际上我们的设备&#xff0c;有时候并没有服务器那么厉害&#xff0c;所以人…

阿里云认证为什么那么多人考?考试内容难不难?

我国人口密集&#xff0c;每年有大量的毕业生涌进社会&#xff0c;除此之外还有很多进入社会很久的打工人&#xff0c;想要跳槽&#xff0c;到更加挣钱的岗位&#xff0c;待遇更好的公司去。为了能够早日买房、买车&#xff0c;很多人会选择社会热门行业去学习&#xff0c;甚至…

sqli-labs 第七关 多命通关攻略

sqli-labs 第七关 多命通关攻略描述字符串与数值之间的转换判断注入类型返回结果正常输入不正常输入错误输入总结判断注入类型判断是否为字符型注入判断是否为单引号字符型注入判断是否为双引号字符型注入判断是否为数值型注入总结判断注入类型&#xff08;修正版&#xff09;字…