rk3588上完成halcon的形状模型配准以及和opencv的图像转换

一、准备工作

1)安装好halcon,确保halcon的c++的调用是正常的

2)编译好opencv

上面的两个步骤,均可以参考我的两个博文完成:

Halcon在linux及ARM上的安装及c++工程化_halcon linux-CSDN博客

RK3588上编译opencv 及基于c++实现图像的读入-CSDN博客

二、代码准备

2.1 基于c++的opencv和halcon之间的图像的转换代码

cpp 复制代码
// 将halcon图像转换为opencv的图像
Mat HImageToMat(HObject &imgHalcon)
{
    HTuple channels;
    HString cType;
    cv::Mat Image;
    ConvertImageType(imgHalcon, &imgHalcon, "byte");
    CountChannels(imgHalcon, &channels);
    Hlong width = 0;
    Hlong height = 0;
    if (channels[0].I() == 1)
    {
        HImage hImg(imgHalcon);
        void *ptr = hImg.GetImagePointer1(&cType, &width, &height);//GetImagePointer1(Hobj, &ptr, &cType, &wid, &hgt);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC1);
        unsigned char *pdata = static_cast<unsigned char *>(ptr);
        memcpy(Image.data, pdata, W*H);
    }
    else if (channels[0].I() == 3)
    {
        void *Rptr;
        void *Gptr;
        void *Bptr;
        HImage hImg(imgHalcon);
        hImg.GetImagePointer3(&Rptr, &Gptr, &Bptr, &cType, &width, &height);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC3);
        vector<cv::Mat> VecM(3);
        VecM[0].create(H, W, CV_8UC1);
        VecM[1].create(H, W, CV_8UC1);
        VecM[2].create(H, W, CV_8UC1);
        unsigned char *R = (unsigned char *)Rptr;
        unsigned char *G = (unsigned char *)Gptr;
        unsigned char *B = (unsigned char *)Bptr;
        memcpy(VecM[2].data, R, W*H);
        memcpy(VecM[1].data, G, W*H);
        memcpy(VecM[0].data, B, W*H);
        cv::merge(VecM, Image);
    }
    return Image;
}

//OpenCV Mat -> Halcon HObject​
HObject MatToHImage(Mat &imgMat)
{
    HObject Hobj = HObject();
    int height = imgMat.rows;
    int width = imgMat.cols;
    int i;
    //  CV_8UC3
    if (imgMat.type() == CV_8UC3)
    {
        vector<cv::Mat> imgchannel;
        split(imgMat, imgchannel);
        cv::Mat imgB = imgchannel[0];
        cv::Mat imgG = imgchannel[1];
        cv::Mat imgR = imgchannel[2];
        uchar* dataR = new uchar[height * width];
        uchar* dataG = new uchar[height * width];
        uchar* dataB = new uchar[height * width];
        for (i = 0; i<height; i++)
        {
            memcpy(dataR + width*i, imgR.data + imgR.step*i, width);
            memcpy(dataG + width*i, imgG.data + imgG.step*i, width);
            memcpy(dataB + width*i, imgB.data + imgB.step*i, width);
        }
        GenImage3(&Hobj, "byte", width, height, (Hlong)dataR, (Hlong)dataG, (Hlong)dataB);
        delete[]dataR;
        delete[]dataG;
        delete[]dataB;
    }
    //  CV_8UCU1
    else if (imgMat.type() == CV_8UC1)
    {
        uchar* data = new uchar[height*width];
        for (i = 0; i<height; i++)
            memcpy(data + width*i, imgMat.data + imgMat.step*i, width);
        GenImage1(&Hobj, "byte", width, height, (Hlong)data);
        delete[] data;
    }
    return Hobj;
}

2.2 创建一个总执行的cpp

HalconDemo.cpp

cpp 复制代码
#include <iostream>
 
#include <halconcpp/HalconCpp.h>
#include <opencv2/opencv.hpp>


using namespace HalconCpp;
using namespace std;
using namespace cv;


// 将halcon图像转换为opencv的图像
Mat HImageToMat(HObject &imgHalcon)
{
    HTuple channels;
    HString cType;
    cv::Mat Image;
    ConvertImageType(imgHalcon, &imgHalcon, "byte");
    CountChannels(imgHalcon, &channels);
    Hlong width = 0;
    Hlong height = 0;
    if (channels[0].I() == 1)
    {
        HImage hImg(imgHalcon);
        void *ptr = hImg.GetImagePointer1(&cType, &width, &height);//GetImagePointer1(Hobj, &ptr, &cType, &wid, &hgt);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC1);
        unsigned char *pdata = static_cast<unsigned char *>(ptr);
        memcpy(Image.data, pdata, W*H);
    }
    else if (channels[0].I() == 3)
    {
        void *Rptr;
        void *Gptr;
        void *Bptr;
        HImage hImg(imgHalcon);
        hImg.GetImagePointer3(&Rptr, &Gptr, &Bptr, &cType, &width, &height);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC3);
        vector<cv::Mat> VecM(3);
        VecM[0].create(H, W, CV_8UC1);
        VecM[1].create(H, W, CV_8UC1);
        VecM[2].create(H, W, CV_8UC1);
        unsigned char *R = (unsigned char *)Rptr;
        unsigned char *G = (unsigned char *)Gptr;
        unsigned char *B = (unsigned char *)Bptr;
        memcpy(VecM[2].data, R, W*H);
        memcpy(VecM[1].data, G, W*H);
        memcpy(VecM[0].data, B, W*H);
        cv::merge(VecM, Image);
    }
    return Image;
}

//OpenCV Mat -> Halcon HObject​
HObject MatToHImage(Mat &imgMat)
{
    HObject Hobj = HObject();
    int height = imgMat.rows;
    int width = imgMat.cols;
    int i;
    //  CV_8UC3
    if (imgMat.type() == CV_8UC3)
    {
        vector<cv::Mat> imgchannel;
        split(imgMat, imgchannel);
        cv::Mat imgB = imgchannel[0];
        cv::Mat imgG = imgchannel[1];
        cv::Mat imgR = imgchannel[2];
        uchar* dataR = new uchar[height * width];
        uchar* dataG = new uchar[height * width];
        uchar* dataB = new uchar[height * width];
        for (i = 0; i<height; i++)
        {
            memcpy(dataR + width*i, imgR.data + imgR.step*i, width);
            memcpy(dataG + width*i, imgG.data + imgG.step*i, width);
            memcpy(dataB + width*i, imgB.data + imgB.step*i, width);
        }
        GenImage3(&Hobj, "byte", width, height, (Hlong)dataR, (Hlong)dataG, (Hlong)dataB);
        delete[]dataR;
        delete[]dataG;
        delete[]dataB;
    }
    //  CV_8UCU1
    else if (imgMat.type() == CV_8UC1)
    {
        uchar* data = new uchar[height*width];
        for (i = 0; i<height; i++)
            memcpy(data + width*i, imgMat.data + imgMat.step*i, width);
        GenImage1(&Hobj, "byte", width, height, (Hlong)data);
        delete[] data;
    }
    return Hobj;
}
 
Mat shape_find(cv::Mat image_opencv)
{
    // Local iconic variables
  HObject  ho_Image800, ho_ROI_0, ho_ImageReduced;
  HObject  ho_ImagePart, ho_ImageReduced1, ho_Imagetest, ho_rImage;
  HObject  ho_ImageAffineTrans, ho_SymbolXLDs;

  // Local control variables
  HTuple  hv_Area, hv_RowModel, hv_ColumnModel;
  HTuple  hv_ModelID1, hv_StartSeconds, hv_Row, hv_Column;
  HTuple  hv_Angle, hv_Scale1, hv_Score1, hv_model, hv_EndSeconds;
  HTuple  hv_HomMat2DImage, hv_DataCodeHandle, hv_ResultHandles;
  HTuple  hv_DecodedDataStrings;
  cv::Mat image;


  //加上这句就可以了,因为画的模板框在旋转到右边和左边时超出了图像范围,要允许与边缘相交才能找到
  SetSystem("border_shape_models", "true");
  SetSystem("int_zooming", "true");



  //ReadImage(&ho_Image800, "../images/8.bmp");

  ho_Image800=MatToHImage(image_opencv);


  GenRectangle1(&ho_ROI_0, 2.06, 286.751, 1778.7, 2959.32);
  ReduceDomain(ho_Image800, ho_ROI_0, &ho_ImageReduced);
  CropDomain(ho_ImageReduced, &ho_ImagePart);



  GenRectangle1(&ho_ROI_0, 763.171, 559.159, 1444.96, 2025.97);
  ReduceDomain(ho_ImagePart, ho_ROI_0, &ho_ImageReduced1);
  AreaCenter(ho_ROI_0, &hv_Area, &hv_RowModel, &hv_ColumnModel);
  CreateScaledShapeModel(ho_ImageReduced1, "auto", HTuple(0).TupleRad(), HTuple(360).TupleRad(), 
      HTuple(0.2).TupleRad(), 0.5, 2, "auto", "auto", "use_polarity", 40, 30, &hv_ModelID1);




  ReadImage(&ho_Imagetest, "../images/9.bmp");
  GenRectangle1(&ho_ROI_0, 2.06, 286.751, 1778.7, 2959.32);
  ReduceDomain(ho_Imagetest, ho_ROI_0, &ho_ImageReduced);
  CropDomain(ho_ImageReduced, &ho_rImage);



  CountSeconds(&hv_StartSeconds);
  FindScaledShapeModels(ho_rImage, hv_ModelID1, HTuple(0).TupleRad(), HTuple(360).TupleRad(), 
      0.5, 2, 0.4, 1, 1, "least_squares_high", (HTuple(5).Append(3)), 0.9, &hv_Row, 
      &hv_Column, &hv_Angle, &hv_Scale1, &hv_Score1, &hv_model);

    
  CountSeconds(&hv_EndSeconds);
  if (0 != (int((hv_Row.TupleLength())>0)))
  {

    std::cout << "find shape is ok " << endl;
    VectorAngleToRigid(HTuple(hv_Row[0]), HTuple(hv_Column[0]), hv_Angle, HTuple(hv_RowModel[0]), 
        HTuple(hv_ColumnModel[0]), 0, &hv_HomMat2DImage);
    AffineTransImage(ho_rImage, &ho_ImageAffineTrans, hv_HomMat2DImage, "constant", "false");

    CreateDataCode2dModel("QR Code", HTuple(), HTuple(), &hv_DataCodeHandle);
    FindDataCode2d(ho_ImageAffineTrans, &ho_SymbolXLDs, hv_DataCodeHandle, HTuple(), 
        HTuple(), &hv_ResultHandles, &hv_DecodedDataStrings);
    
    std::cout << "QR Code" << ":" << hv_DecodedDataStrings.S() << endl;

    image=HImageToMat(ho_ImageAffineTrans);

  }

    return image;
}


int main()
{
    Mat image;

    Mat image_opencv = imread("../9.bmp");
    if (image_opencv.empty()) {
        std::cerr << "Error opening image!" << std::endl;
        return -1;
    }


    image=shape_find(image_opencv);
    cout<<"hello";
    std::string outputPath = "result.bmp"; 
    imwrite(outputPath,image);
    return 0;
}

2.3 CMakeLists.txt

bash 复制代码
cmake_minimum_required(VERSION 3.0.0)
project(HalconDemo VERSION 0.1.0)
 
set(TARGET_NAME HalconDemo)
 
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)

set(OpenCV_DIR "/usr/local/opencv470")  # 根据实际安装路径修改
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
 
 
# 添加头文件搜索路径  
include_directories(include)
 
link_directories(/opt/halcon/lib/aarch64-linux)
 
aux_source_directory(. SRCS )
 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -static-libstdc++ -fPIC -Wl,--copy-dt-needed-entries -Wno-error=deprecated-declarations -Wno-deprecated-declarations ")
 
# 寻找./src下面所有.cpp为后缀的源文件,并且保存到SRC变量里面  
file(GLOB_RECURSE SRC ./src/*.cpp)  
  
# 编译SRC变量存储的源文件,编译生成目标文件命名为hello  
add_executable(hello ${SRC})
#add_library(hello SHARED src/HalconDemo.cpp)
target_link_libraries(hello halcon halconcpp hdevenginecpp)
target_link_libraries(hello ${OpenCV_LIBS}) 

2.4 编译及运行

mkdir build

cd build

cmake ..

make

./hello

相关推荐
zm-v-159304339862 分钟前
解锁遥感数据密码:DeepSeek、Python 与 OpenCV 的协同之力
开发语言·python·opencv
jndingxin1 小时前
OpenCV CUDA 模块中在 GPU 上对图像或矩阵进行 翻转(镜像)操作的一个函数 flip()
人工智能·opencv
码农新猿类2 小时前
初入OpenCV
qt·opencv·计算机视觉
程序小K5 小时前
OpenCV的CUDA模块进行图像处理
图像处理·人工智能·opencv
jndingxin5 小时前
OpenCVCUDA 模块中在 GPU 上对图像或矩阵进行 边界填充(padding)函数copyMakeBorder()
人工智能·opencv
jndingxin16 小时前
OpenCV 的 CUDA 模块中用于将多个单通道的 GpuMat 图像合并成一个多通道的图像 函数cv::cuda::merge
人工智能·opencv·计算机视觉
巷95518 小时前
OpenCV图像金字塔详解:原理、实现与应用
人工智能·opencv·计算机视觉
小草cys1 天前
树莓派4 yolo 11l.pt性能优化后的版本
opencv·计算机视觉·目标跟踪
Blossom.1181 天前
探索边缘计算:赋能物联网的未来
开发语言·人工智能·深度学习·opencv·物联网·机器学习·边缘计算
(ღ星辰ღ)1 天前
js应用opencv
开发语言·javascript·opencv