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

相关推荐
全栈开发圈3 小时前
新书速览|OpenCV计算机视觉开发实践:基于Qt C++
qt·opencv·计算机视觉
bjxiaxueliang9 小时前
一文详解opencv-python环境搭建:Mac配置python的cv2开发环境
python·opencv·macos
绝顶大聪明14 小时前
【图像轮廓特征查找】图像处理(OpenCV) -part8
图像处理·人工智能·opencv
Blossom.11814 小时前
量子计算与经典计算融合:开启计算新时代
人工智能·深度学习·opencv·物联网·生活·边缘计算·量子计算
2401_8786247915 小时前
opencv HSV的具体描述
人工智能·opencv·计算机视觉
2401_8786247915 小时前
opencv 给图片和视频添加水印
人工智能·opencv·计算机视觉
白熊1881 天前
【计算机视觉】CV实战项目- COVID 社交距离检测(covid-social-distancing-detection)
人工智能·opencv·计算机视觉
暴富奥利奥1 天前
基于 OpenCV 的图像与视频处理
opencv·学习
绝顶大聪明1 天前
[图像掩膜,ROI切割] 图像预处理(OpenCV)-part4
人工智能·opencv·计算机视觉