欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Opencv&Halcon混合编程

程序员文章站 2022-05-30 13:22:52
...

前言

Halcon 具备一些非常强大的算子,特别是其中的模板匹配功能,因此在建立自己的解决方案时,灵活的运用Halcon与OpenCV往往会事半功倍。

1. 编写halcon代码

Opencv&Halcon混合编程

以halcon中的find_scaled_shape_model为例。

 

2. 导出halcon代码到C++

Opencv&Halcon混合编程

 

删除掉被宏定义注释的代码,主要关注action函数里面的代码。

删除窗口显示相关代码。

 

3. 头文件和库文件

添加头文件和库文件路径

 

将DLL文件拷贝到可执行文件目录下

4. 格式转换

Halcon C++ 中存在两种数据结构Hobject和HTuple。

Halcon中没有很多复杂的数据结构,在Opencv中使用结构体或类表示的数据结构在Halcon中通常采用一系列变量来表示。

HObject不都是image类型,只有image类型才可以转为Mat。

 

Halcon中的数据结构:

Image

可以转化为Mat。

 

Region

可以使用Halcon的region_to_bin将区域转为二进制字节图像,再转为Mat。

region_to_bin (Region, BinImage, 255, 0, Width, Height)

Mat HalconCV::RegionToMat(HObject ho_Region, HTuple  hv_Width, HTuple  hv_Height)
{
    HObject ho_BinImage;
    RegionToBin(ho_Region, &ho_BinImage, 255, 0, hv_Width, hv_Height);
    return HobjectToMat(ho_BinImage);
}

 

Contour

可以使用Halcon中的contour_point_num_xld(Contour : : : Length)将轮廓转化为一系列点集。

 

 

 

例如在Opencv中使用Rect来表示矩形,在halcon中则使用四个单独的变量表示,所以解析起来也很容易。

 

字符串与HTuple互转

char *pImageName = "D:/data/temp.png";
HTuple hv_path;
hv_path = (HTuple)(pImageName);
string path = hv_path.S();

Double与HTuple互转

HTuple hv_data;
hv_data = 10.0;
double data = hv_path.D();

Mat转HObject

HObject matToHobject(Mat& image)
{
    HObject Hobj = HObject();
    int hgt = image.rows;
    int wid = image.cols;
    int i;
//  CV_8UC3  
    if (image.type() == CV_8UC3)
    {
        vector<Mat> imgchannel;
        split(image, imgchannel);
        Mat imgB = imgchannel[0];
        Mat imgG = imgchannel[1];
        Mat imgR = imgchannel[2];
        uchar* dataR = new uchar[hgt*wid];
        uchar* dataG = new uchar[hgt*wid];
        uchar* dataB = new uchar[hgt*wid];
        for (i = 0; i < hgt; i++)
        {
            memcpy(dataR + wid*i, imgR.data + imgR.step*i, wid);
            memcpy(dataG + wid*i, imgG.data + imgG.step*i, wid);
            memcpy(dataB + wid*i, imgB.data + imgB.step*i, wid);
        }
        GenImage3(&Hobj, "byte", wid, hgt, (Hlong)dataR, (Hlong)dataG, (Hlong)dataB);
        delete[]dataR;
        delete[]dataG;
        delete[]dataB;
        dataR = NULL;
        dataG = NULL;
        dataB = NULL;
    }

        //  CV_8UCU1  
    else if (image.type() == CV_8UC1)
    {
        uchar* data = new uchar[hgt*wid];
        for (i = 0; i < hgt; i++)
            memcpy(data + wid*i, image.data + image.step*i, wid);
        GenImage1(&Hobj, "byte", wid, hgt, (Hlong)data);
        delete[] data;
        data = NULL;
    }
    return Hobj;
}

HObject转Mat

Mat HobjectToMat(HObject Hobj)
{
    HTuple htCh = HTuple();
    HTuple cTyp
    Mat Image;
    ConvertImageType(Hobj, &Hobj, "byte");
    CountChannels(Hobj, &htCh);
    HTuple wid;
    HTuple hgt;
    int W, H;
    if (htCh[0].I() == 1)
    {
        HTuple ptr;
        GetImagePointer1(Hobj, &ptr, &cType, &wid, &hgt);
        W = (Hlong)wid;
        H = (Hlong)hgt;
        Image.create(H, W, CV_8UC1);
        uchar* pdata = (uchar*)ptr[0].I();
        memcpy(Image.data, pdata, W*H);
    }
    else if (htCh[0].I() == 3)
    {
        HTuple ptrR, ptrG, ptrB;
        GetImagePointer3(Hobj, &ptrR, &ptrG, &ptrB, &cType, &wid, &hgt);
        W = (Hlong)wid;
        H = (Hlong)hgt;
        Image.create(H, W, CV_8UC3);
        vector<Mat> vecM(3);
        vecM[2].create(H, W, CV_8UC1);
        vecM[1].create(H, W, CV_8UC1);
        vecM[0].create(H, W, CV_8UC1);
        uchar* pr = (uchar*)ptrR[0].I();
        uchar* pg = (uchar*)ptrG[0].I();
        uchar* pb = (uchar*)ptrB[0].I();
        memcpy(vecM[2].data, pr, W*H);
        memcpy(vecM[1].data, pg, W*H);
        memcpy(vecM[0].data, pb, W*H);
        merge(vecM, Image);
    }
    return Image;
}

5. 混合编程

混合编程最重要的就是对输入输出的格式转换,中间的处理过程可以封装为函数,不做考虑。

#include "halconcv.h"
using namespace HalconCpp;
void action()
{
  // Local iconic variables
  HObject  ho_Image, ho_Region, ho_ConnectedRegions;
  HObject  ho_SelectedRegions, ho_RegionFillUp, ho_RegionDilation;
  HObject  ho_ImageReduced, ho_Model, ho_ModelTrans, ho_ImageSearch;

  // Local control variables
  HTuple  hv_Width, hv_Height;
  HTuple  hv_ModelID, hv_Area, hv_RowRef, hv_ColumnRef, hv_HomMat2D;
  HTuple  hv_Row, hv_Column, hv_Angle, hv_Scale, hv_Score;
  HTuple  hv_Row1, hv_Column1, hv_Row2, hv_Column2;
  HTuple  hv_I;

  cv::Mat src = cv::imread("green-dot.png", 1);
  ho_Image = HalconCV::matToHobject(src);

  GetImageSize(ho_Image, &hv_Width, &hv_Height);
  Threshold(ho_Image, &ho_Region, 0, 128);
  Connection(ho_Region, &ho_ConnectedRegions);

  SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 10000, 20000);
  FillUp(ho_SelectedRegions, &ho_RegionFillUp);
  DilationCircle(ho_RegionFillUp, &ho_RegionDilation, 5.5);

  ReduceDomain(ho_Image, ho_RegionDilation, &ho_ImageReduced);
  CreateScaledShapeModel(ho_ImageReduced, 5, HTuple(-45).TupleRad(), HTuple(90).TupleRad(),

      "auto", 0.8, 1.0, "auto", "none", "ignore_global_polarity", 40, 10, &hv_ModelID);

  GetShapeModelContours(&ho_Model, hv_ModelID, 1);
  AreaCenter(ho_RegionFillUp, &hv_Area, &hv_RowRef, &hv_ColumnRef);
  VectorAngleToRigid(0, 0, 0, hv_RowRef, hv_ColumnRef, 0, &hv_HomMat2D);
  AffineTransContourXld(ho_Model, &ho_ModelTrans, hv_HomMat2D);

  cv::Mat image_search = cv::imread("green-dots.png", 1);
  ho_ImageSearch = HalconCV::matToHobject(image_search);
  FindScaledShapeModel(ho_ImageSearch, hv_ModelID, HTuple(-45).TupleRad(), HTuple(90).TupleRad(),
      0.8, 1.0, 0.5, 0, 0.5, "least_squares", 5, 0.8, &hv_Row, &hv_Column, &hv_Angle,
      &hv_Scale, &hv_Score);

  {
      HTuple end_val26 = (hv_Score.TupleLength())-1;
      HTuple step_val26 = 1;
      for (hv_I=0; hv_I.Continue(end_val26, step_val26); hv_I += step_val26)
      {
        double offset_x = hv_Column[hv_I];
        double offset_y = hv_Row[hv_I];
        double angle = hv_Angle[hv_I];
        double scale = hv_Scale[hv_I];
        cv::circle(image_search, cv::Point2f(offset_x, offset_y), 1, cv::Scalar(0, 255, 0), 5);
        std::cout << offset_x << " "<< offset_y << " "<< angle << " "<< scale << std::endl;
      }
  }
  cv::imshow("src", src);
  waitKey(0);
  ClearShapeModel(hv_ModelID);
}


int main(int argc, char *argv[])
{
  int ret = 0;
  try
  {
    SetSystem("use_window_thread", "true");
    SetSystem("width", 512);
    SetSystem("height", 512);
    action();
  }
  catch (HException &exception)
  {
    fprintf(stderr,"  Error #%u in %s: %s\n", exception.ErrorCode(),
            (const char *)exception.ProcName(),
            (const char *)exception.ErrorMessage());
    ret = 1;
  }
  return ret;
}

 

相关标签: Image Processing