Halcon-Yolo联合缺陷检测

发布于:2025-02-26 ⋅ 阅读:(160) ⋅ 点赞:(0)

C#

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using HalconDotNet;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
namespace Halcon2Yolov8Seg
{
    class Program
    {
        public static void HobjectToMat(HObject ho_Img, out Mat dst)
        {
            dst = new Mat();
            HTuple ht_Channels = null;
            HTuple ht_Type = null;
            HTuple ht_Width = null, ht_Height = null;
            try
            {
                HOperatorSet.CountChannels(ho_Img, out ht_Channels);
                if (ht_Channels.Length == 0)
                {
                    return;
                }
                if (ht_Channels[0].I == 1)
                {
                    HTuple ht_Pointer = null;
                    IntPtr intPtr = IntPtr.Zero;
                    HOperatorSet.GetImagePointer1(ho_Img, out ht_Pointer, out ht_Type, out ht_Width, out ht_Height);
                    intPtr = ht_Pointer;
                    dst = Mat.FromPixelData(ht_Height, ht_Width, MatType.CV_8UC1, intPtr);
                }
                else if (ht_Channels[0].I == 3)
                {
                    HTuple ht_ptrRed = null;
                    HTuple ht_ptrGreen = null;
                    HTuple ht_ptrBlue = null;
                    IntPtr ptrRed = IntPtr.Zero;
                    IntPtr ptrGreen = IntPtr.Zero;
                    IntPtr ptrBlue = IntPtr.Zero;
                    HOperatorSet.GetImagePointer3(ho_Img, out ht_ptrRed, out ht_ptrGreen, out ht_ptrBlue, out ht_Type, out ht_Width, out ht_Height);
                    ptrRed = ht_ptrRed;
                    ptrGreen = ht_ptrGreen;
                    ptrBlue = ht_ptrBlue;
                    Mat matRed = new Mat();
                    Mat matGreen = new Mat();
                    Mat matBlue = new Mat();
                    matRed = Mat.FromPixelData(ht_Height, ht_Width, MatType.CV_8UC1, ptrRed);
                    matGreen = Mat.FromPixelData(ht_Height, ht_Width, MatType.CV_8UC1, ptrGreen);
                    matBlue = Mat.FromPixelData(ht_Height, ht_Width, MatType.CV_8UC1, ptrBlue);
                    Mat[] multi = new Mat[] { matBlue, matGreen, matRed };
                    Cv2.Merge(multi, dst);
                    matBlue.Dispose();
                    matGreen.Dispose();
                    matRed.Dispose();
                }
            }
            catch (Exception ex)
            {
            }
        }
        public static void MatToHObject(Mat src, out HObject ho_Img)
        {
            ho_Img = new HObject();
            try
            {
                if (src.Channels() == 1)
                {
                    unsafe
                    {
                        HOperatorSet.GenImage1(out ho_Img, "byte", src.Width, src.Height, src.Data);
                    }
                }
                else if (src.Channels() == 3)
                {
                    Mat[] mats = new Mat[3];
                    Cv2.Split(src, out mats);
                    unsafe
                    {
                        HOperatorSet.GenImage3(out ho_Img, "byte", src.Width, src.Height, mats[2].Data, mats[1].Data, mats[0].Data);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
        private static float sigmoid(float a)
        {
            float b = 1.0f / (1.0f + (float)Math.Exp(-a));
            return b;
        }
        public static string[] read_class_names(string path)
        {
            string[] class_names;
            List<string> str = new List<string>();
            StreamReader sr = new StreamReader(path);
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                str.Add(line);
            }
            class_names = str.ToArray();
            return class_names;
        }
        static void Main(string[] args)
        {
            float conf_threshold = 0.25f;
            float nms_threshold = 0.5f;
            string model_path = "yolov8n-seg.onnx";
            string image_path = "bus_transform.jpg";
            string[] classes_names = read_class_names("coco.names");
            HObject ho_Input, ho_Region, ho_RegionClosing;
            HObject ho_ImageReduced, ho_ImagePart, ho_Image, ho_Image_Result;
            HObject ho_GrayImage_Result, ho_Rectangle;
            HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
            HTuple hv_Area = new HTuple(), hv_Row_Loc = new HTuple();
            HTuple hv_Column_Loc = new HTuple(), hv_Width_S = new HTuple();
            HTuple hv_Height_S = new HTuple(), hv_Rows = new HTuple();
            HTuple hv_Cols = new HTuple(), hv_Grayvals = new HTuple();
            HTuple hv_offset_X = new HTuple(), hv_offset_Y = new HTuple();
            HOperatorSet.GenEmptyObj(out ho_Input);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_RegionClosing);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_ImagePart);
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_Image_Result);
            HOperatorSet.GenEmptyObj(out ho_GrayImage_Result);
            HOperatorSet.GenEmptyObj(out ho_Rectangle);
            HOperatorSet.ReadImage(out ho_Input, image_path);
            HOperatorSet.GetImageSize(ho_Input, out hv_Width, out hv_Height);
            HOperatorSet.Threshold(ho_Input, out ho_Region, 1, 255);
            HOperatorSet.ClosingCircle(ho_Region, out ho_RegionClosing, 10);
            HOperatorSet.ReduceDomain(ho_Input, ho_RegionClosing, out ho_ImageReduced);
            HOperatorSet.CropDomain(ho_ImageReduced, out ho_ImagePart);
            HOperatorSet.AreaCenter(ho_RegionClosing, out hv_Area, out hv_Row_Loc, out hv_Column_Loc);
            HOperatorSet.GenImageConst(out ho_Image, "byte", hv_Width, hv_Height);
            Mat masked_img = new Mat();
            List<NamedOnnxValue> input_ontainer;
            List<Rect> position_boxes = new List<Rect>();
            List<int> class_ids = new List<int>();
            List<float> class_scores = new List<float>();
            List<float> confidences = new List<float>();
            List<Mat> masks = new List<Mat>();
            Tensor<float> result_tensors_det;
            Tensor<float> result_tensors_proto;
            SessionOptions options;
            InferenceSession onnx_session;
            Tensor<float> input_tensor;
            IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
            DisposableNamedOnnxValue[] results_onnxvalue;
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);
            onnx_session = new InferenceSession(model_path, options);
            input_ontainer = new List<NamedOnnxValue>();
            Mat image;
            HobjectToMat(ho_ImagePart, out image);
            int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
            Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
            Rect roi = new Rect(0, 0, image.Cols, image.Rows);
            image.CopyTo(new Mat(max_image, roi));
            float[] det_result_array = new float[25200 * 116];
            float[] proto_result_array = new float[32 * 160 * 160];
            float[] factors = new float[4];
            factors[0] = factors[1] = (float)(max_image_length / 640.0);
            factors[2] = image.Rows;
            factors[3] = image.Cols;
            Mat image_rgb = new Mat();
            Mat resize_image = new Mat();
            Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB);
            Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));
            input_tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 });
            for (int y = 0; y < resize_image.Height; y++)
            {
                for (int x = 0; x < resize_image.Width; x++)
                {
                    input_tensor[0, 0, y, x] = resize_image.At<Vec3b>(y, x)[0] / 255f;
                    input_tensor[0, 1, y, x] = resize_image.At<Vec3b>(y, x)[1] / 255f;
                    input_tensor[0, 2, y, x] = resize_image.At<Vec3b>(y, x)[2] / 255f;
                }
            }
            input_ontainer.Add(NamedOnnxValue.CreateFromTensor("images", input_tensor));
            result_infer = onnx_session.Run(input_ontainer);
            results_onnxvalue = result_infer.ToArray();
            result_tensors_det = results_onnxvalue[0].AsTensor<float>();
            result_tensors_proto = results_onnxvalue[1].AsTensor<float>();
            det_result_array = result_tensors_det.ToArray();
            proto_result_array = result_tensors_proto.ToArray();
            Mat detect_data = Mat.FromPixelData(116, 8400, MatType.CV_32F, det_result_array);
            Mat proto_data = Mat.FromPixelData(32, 25600, MatType.CV_32F, proto_result_array);
            detect_data = detect_data.T();
            for (int i = 0; i < detect_data.Rows; i++)
            {
                Mat classes_scores = detect_data.Row(i).ColRange(4, 84);
                Point max_classId_point, min_classId_point;
                double max_score, min_score;
                Cv2.MinMaxLoc(classes_scores, out min_score, out max_score,
                    out min_classId_point, out max_classId_point);
                if (max_score > 0.25)
                {
                    Mat mask = detect_data.Row(i).ColRange(84, 116);
                    float cx = detect_data.At<float>(i, 0);
                    float cy = detect_data.At<float>(i, 1);
                    float ow = detect_data.At<float>(i, 2);
                    float oh = detect_data.At<float>(i, 3);
                    int x = (int)((cx - 0.5 * ow) * factors[0]);
                    int y = (int)((cy - 0.5 * oh) * factors[1]);
                    int width = (int)(ow * factors[0]);
                    int height = (int)(oh * factors[1]);
                    Rect box = new Rect();
                    box.X = x;
                    box.Y = y;
                    box.Width = width;
                    box.Height = height;
                    position_boxes.Add(box);
                    class_ids.Add(max_classId_point.X);
                    classes_scores.Add((Scalar)max_score);
                    confidences.Add((float)max_score);
                    masks.Add(mask);
                }
            }
            int[] indexes = new int[position_boxes.Count];
            CvDnn.NMSBoxes(position_boxes, confidences, conf_threshold, nms_threshold, out indexes);
            Mat rgb_mask = Mat.Zeros(new Size((int)factors[3], (int)factors[2]), MatType.CV_8UC3);
            Random rd = new Random();
            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];
                Rect box = position_boxes[index];
                int box_x1 = Math.Max(0, box.X);
                int box_y1 = Math.Max(0, box.Y);
                int box_x2 = Math.Max(0, box.BottomRight.X);
                int box_y2 = Math.Max(0, box.BottomRight.Y);
                Mat original_mask = masks[index] * proto_data;
                for (int col = 0; col < original_mask.Cols; col++)
                {
                    original_mask.At<float>(0, col) = sigmoid(original_mask.At<float>(0, col));
                }
                Mat reshape_mask = original_mask.Reshape(1, 160);
                int mx1 = Math.Max(0, (int)((box_x1 / factors[0]) * 0.25));
                int mx2 = Math.Max(0, (int)((box_x2 / factors[0]) * 0.25));
                int my1 = Math.Max(0, (int)((box_y1 / factors[1]) * 0.25));
                int my2 = Math.Max(0, (int)((box_y2 / factors[1]) * 0.25));
                Mat mask_roi = new Mat(reshape_mask, new OpenCvSharp.Range(my1, my2), new OpenCvSharp.Range(mx1, mx2));
                Mat actual_maskm = new Mat();
                Cv2.Resize(mask_roi, actual_maskm, new Size(box_x2 - box_x1, box_y2 - box_y1));
                for (int r = 0; r < actual_maskm.Rows; r++)
                {
                    for (int c = 0; c < actual_maskm.Cols; c++)
                    {
                        float pv = actual_maskm.At<float>(r, c);
                        if (pv > 0.5)
                        {
                            actual_maskm.At<float>(r, c) = 1.0f;
                        }
                        else
                        {
                            actual_maskm.At<float>(r, c) = 0.0f;
                        }
                    }
                }
                Mat bin_mask = new Mat();
                actual_maskm = actual_maskm * 200;
                actual_maskm.ConvertTo(bin_mask, MatType.CV_8UC1);
                if ((box_y1 + bin_mask.Rows) >= factors[2])
                {
                    box_y2 = (int)factors[2] - 1;
                }
                if ((box_x1 + bin_mask.Cols) >= factors[3])
                {
                    box_x2 = (int)factors[3] - 1;
                }
                Mat mask = Mat.Zeros(new Size((int)factors[3], (int)factors[2]), MatType.CV_8UC1);
                bin_mask = new Mat(bin_mask, new OpenCvSharp.Range(0, box_y2 - box_y1), new OpenCvSharp.Range(0, box_x2 - box_x1));
                Rect rois = new Rect(box_x1, box_y1, box_x2 - box_x1, box_y2 - box_y1);
                bin_mask.CopyTo(new Mat(mask, rois));
                Cv2.Add(rgb_mask, new Scalar(rd.Next(0, 255), rd.Next(0, 255), rd.Next(0, 255)), rgb_mask, mask);
                Cv2.Rectangle(image, position_boxes[index], new Scalar(0, 0, 255), 2, LineTypes.Link8);
                Cv2.Rectangle(image, new Point(position_boxes[index].TopLeft.X, position_boxes[index].TopLeft.Y - 20),
                    new Point(position_boxes[index].BottomRight.X, position_boxes[index].TopLeft.Y), new Scalar(0, 255, 255), -1);
                Cv2.PutText(image, classes_names[class_ids[index]] + "-" + confidences[index].ToString("0.00"),
                    new Point(position_boxes[index].X, position_boxes[index].Y - 10),
                    HersheyFonts.HersheySimplex, 0.6, new Scalar(0, 0, 0), 1);
                Cv2.AddWeighted(image, 0.5, rgb_mask.Clone(), 0.5, 0, masked_img);
            }
            MatToHObject(rgb_mask, out ho_Image_Result);
            HOperatorSet.Rgb1ToGray(ho_Image_Result, out ho_GrayImage_Result);
            HOperatorSet.GetImageSize(ho_Image_Result, out hv_Width_S, out hv_Height_S);
            HOperatorSet.GenRectangle1(out ho_Rectangle, 0, 0, hv_Height_S - 1, hv_Width_S - 1);
            HOperatorSet.GetRegionPoints(ho_Rectangle, out hv_Rows, out hv_Cols);
            HOperatorSet.GetGrayval(ho_GrayImage_Result, hv_Rows, hv_Cols, out hv_Grayvals);
            hv_offset_X = hv_Row_Loc - (hv_Height_S / 2);
            hv_offset_Y = hv_Column_Loc - (hv_Width_S / 2);
            HTuple ExpTmpLocalVar_Rows = hv_Rows + hv_offset_X;
            hv_Rows = ExpTmpLocalVar_Rows;
            HTuple ExpTmpLocalVar_Cols = hv_Cols + hv_offset_Y;
            hv_Cols = ExpTmpLocalVar_Cols;
            HOperatorSet.SetGrayval(ho_Image, hv_Rows, hv_Cols, hv_Grayvals);
            HOperatorSet.WriteImage(ho_Image, "bmp", 0, "mask");
        }
    }
}

Cpp

#include <fstream>
#include <HalconCpp.h>
#include <opencv2/opencv.hpp>
#include <onnxruntime_cxx_api.h>
using namespace std;
using namespace cv;
using namespace Ort;
using namespace HalconCpp;
Mat HImageToMat(HObject& H_img)
{
    Mat cv_img;
    HTuple channels, w, h;
    ConvertImageType(H_img, &H_img, "byte");
    CountChannels(H_img, &channels);
    if (channels.I() == 1)
    {
        HalconCpp::HTuple pointer;
        GetImagePointer1(H_img, &pointer, nullptr, &w, &h);
        int width = w.I(), height = h.I();
        int size = width * height;
        cv_img = cv::Mat::zeros(height, width, CV_8UC1);
        memcpy(cv_img.data, (void*)(pointer.L()), size);
    }
    else if (channels.I() == 3)
    {
        HTuple pointerR, pointerG, pointerB;
        GetImagePointer3(H_img, &pointerR, &pointerG, &pointerB, nullptr, &w, &h);
        int width = w.I(), height = h.I();
        int size = width * height;
        cv_img = cv::Mat::zeros(height, width, CV_8UC3);
        uchar* R = (uchar*)(pointerR.L());
        uchar* G = (uchar*)(pointerG.L());
        uchar* B = (uchar*)(pointerB.L());
        for (int i = 0; i < height; ++i)
        {
            uchar* p = cv_img.ptr<uchar>(i);
            for (int j = 0; j < width; ++j)
            {
                p[3 * j] = B[i * width + j];
                p[3 * j + 1] = G[i * width + j];
                p[3 * j + 2] = R[i * width + j];
            }
        }
    }
    return cv_img;
}
HObject MatToHImage(Mat& cv_img)
{
    HObject H_img;
    if (cv_img.channels() == 1)
    {
        int height = cv_img.rows, width = cv_img.cols;
        int size = height * width;
        uchar* temp = new uchar[size];
        memcpy(temp, cv_img.data, size);
        GenImage1(&H_img, "byte", width, height, (Hlong)(temp));
        delete[] temp;
    }
    else if (cv_img.channels() == 3)
    {
        int height = cv_img.rows, width = cv_img.cols;
        int size = height * width;
        uchar* B = new uchar[size];
        uchar* G = new uchar[size];
        uchar* R = new uchar[size];
        for (int i = 0; i < height; i++)
        {
            uchar* p = cv_img.ptr<uchar>(i);
            for (int j = 0; j < width; j++)
            {
                B[i * width + j] = p[3 * j];
                G[i * width + j] = p[3 * j + 1];
                R[i * width + j] = p[3 * j + 2];
            }
        }
        GenImage3(&H_img, "byte", width, height, (Hlong)(R), (Hlong)(G), (Hlong)(B));
        delete[] R;
        delete[] G;
        delete[] B;
    }
    return H_img;
}
float sigmoid_function(float a) {
    float b = 1. / (1. + exp(-a));
    return b;
}
vector<string> readClassNames(const string& filename) {
    vector<string> classNames;
    ifstream file(filename);
    if (!file.is_open()) {
        cerr << "Error opening file: " << filename << endl;
        return classNames;
    }
    string line;
    while (getline(file, line)) {
        if (!line.empty()) {
            classNames.push_back(line);
        }
    }
    file.close();
    return classNames;
}
int main(int argc, char** argv)
{
    string filename = "coco.names";
    string imagename = "bus_transform.jpg";
    vector<string> labels = readClassNames(filename);
    string onnxpath = "yolov8n-seg.onnx";
    float conf_threshold = 0.25;
    float nms_threshold = 0.4;
    float score_threshold = 0.25;
    HObject  ho_Input, ho_Region, ho_RegionClosing;
    HObject  ho_ImageReduced, ho_ImagePart, ho_Image, ho_Image_Result;
    HObject  ho_GrayImage_Result, ho_Rectangle;
    HTuple  hv_Width, hv_Height, hv_Area, hv_Row_Loc;
    HTuple  hv_Column_Loc, hv_Width_S, hv_Height_S, hv_Rows;
    HTuple  hv_Cols, hv_Grayvals, hv_offset_X, hv_offset_Y;
    ReadImage(&ho_Input, imagename.c_str());
    GetImageSize(ho_Input, &hv_Width, &hv_Height);
    Threshold(ho_Input, &ho_Region, 1, 255);
    ClosingCircle(ho_Region, &ho_RegionClosing, 10);
    ReduceDomain(ho_Input, ho_RegionClosing, &ho_ImageReduced);
    CropDomain(ho_ImageReduced, &ho_ImagePart);
    Mat image = HImageToMat(ho_ImagePart);
    int ih = image.rows;
    int iw = image.cols;
    AreaCenter(ho_RegionClosing, &hv_Area, &hv_Row_Loc, &hv_Column_Loc);
    wstring modelPath = wstring(onnxpath.begin(), onnxpath.end());
    Env env = Env(ORT_LOGGING_LEVEL_ERROR, "yolov8n-seg");
    SessionOptions session_options;
    session_options.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
    Session session_(env, modelPath.c_str(), session_options);
    vector<string> input_node_names;
    vector<string> output_node_names;
    size_t numInputNodes = session_.GetInputCount();
    size_t numOutputNodes = session_.GetOutputCount();
    AllocatorWithDefaultOptions allocator;
    input_node_names.reserve(numInputNodes);
    int input_w = 0;
    int input_h = 0;
    for (int i = 0; i < numInputNodes; i++) {
        auto input_name = session_.GetInputNameAllocated(i, allocator);
        input_node_names.push_back(input_name.get());
        TypeInfo input_type_info = session_.GetInputTypeInfo(i);
        auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
        auto input_dims = input_tensor_info.GetShape();
        input_w = input_dims[3];
        input_h = input_dims[2];
        cout << "input format: NxCxHxW = " << input_dims[0] << "x" << input_dims[1] << "x" << input_dims[2] << "x" << input_dims[3] << endl;
    }
    for (int i = 0; i < numOutputNodes; i++) {
        auto out_name = session_.GetOutputNameAllocated(i, allocator);
        output_node_names.push_back(out_name.get());
    }
    int output_detect_h = 0;
    int output_detect_w = 0;
    TypeInfo output_detect_type_info = session_.GetOutputTypeInfo(0);
    auto output_detect_tensor_info = output_detect_type_info.GetTensorTypeAndShapeInfo();
    auto output_detect_dims = output_detect_tensor_info.GetShape();
    output_detect_h = output_detect_dims[1];
    output_detect_w = output_detect_dims[2];
    cout << "output detect format : HxW = " << output_detect_h << "x" << output_detect_w << endl;
    int output_proto_h = 0;
    int output_proto_w = 0;
    int output_proto_c = 0;
    TypeInfo output_proto_type_info = session_.GetOutputTypeInfo(1);
    auto output_proto_tensor_info = output_proto_type_info.GetTensorTypeAndShapeInfo();
    auto output_proto_dims = output_proto_tensor_info.GetShape();
    output_proto_h = output_proto_dims[2];
    output_proto_w = output_proto_dims[3];
    output_proto_c = output_proto_dims[1];
    cout << "output proto format : CxHxW = " << output_proto_c << "x" << output_proto_h << "x" << output_proto_w << endl;
    cout << "input: " << input_node_names[0] << " output detect: " << output_node_names[0] <<
        " output proto: " << output_node_names[1] << endl;
    int64 start = getTickCount();
    int w = image.cols;
    int h = image.rows;
    int _max = max(h, w);
    Mat image_ = Mat::zeros(Size(_max, _max), CV_8UC3);
    Rect roi(0, 0, w, h);
    image.copyTo(image_(roi));
    float x_factor = image_.cols / static_cast<float>(input_w);
    float y_factor = image_.rows / static_cast<float>(input_h);
    Mat blob = dnn::blobFromImage(image_, 1 / 255.0, Size(input_w, input_h), Scalar(0, 0, 0), true, false);
    size_t tpixels = input_h * input_w * 3;
    array<int64_t, 4> input_shape_info{ 1, 3, input_h, input_w };
    auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
    Value input_tensor_ = Value::CreateTensor<float>(allocator_info, blob.ptr<float>(), tpixels, input_shape_info.data(), input_shape_info.size());
    const array<const char*, 1> inputNames = { input_node_names[0].c_str() };
    const array<const char*, 2> outNames = { output_node_names[0].c_str() , output_node_names[1].c_str() };
    vector<Value> ort_outputs;
    try {
        ort_outputs = session_.Run(RunOptions{ nullptr }, inputNames.data(), &input_tensor_, 1, outNames.data(), outNames.size());
    }
    catch (exception e) {
        cout << e.what() << endl;
    }
    auto data_detect_shape = ort_outputs[0].GetTensorTypeAndShapeInfo().GetShape();
    float* detect_pdata = ort_outputs[0].GetTensorMutableData<float>();
    Mat output_detect = Mat(Size((int)data_detect_shape[2], (int)data_detect_shape[1]), CV_32F, detect_pdata).t();
    auto data_proto_shape = ort_outputs[1].GetTensorTypeAndShapeInfo().GetShape();
    float* proto_pdata = ort_outputs[1].GetTensorMutableData<float>();
    Mat output_proto = Mat(Size((int)(data_proto_shape[2]) * (int)(data_proto_shape[3]), (int)data_proto_shape[1]), CV_32F, proto_pdata);
    vector<Rect> boxes;
    vector<int> classIds;
    vector<float> confidences;
    std::vector<Mat> mask_confs;
    for (int i = 0; i < output_detect.rows; i++) {
        Mat classes_scores = output_detect.row(i).colRange(4, data_detect_shape[1] - data_proto_shape[1]);
        Point classIdPoint;
        double score;
        minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);
        if (score > 0.25)
        {
            float cx = output_detect.at<float>(i, 0);
            float cy = output_detect.at<float>(i, 1);
            float ow = output_detect.at<float>(i, 2);
            float oh = output_detect.at<float>(i, 3);
            int x = static_cast<int>((cx - 0.5 * ow) * x_factor);
            int y = static_cast<int>((cy - 0.5 * oh) * y_factor);
            int width = static_cast<int>(ow * x_factor);
            int height = static_cast<int>(oh * y_factor);
            Rect box;
            box.x = x;
            box.y = y;
            box.width = width;
            box.height = height;
            boxes.push_back(box);
            classIds.push_back(classIdPoint.x);
            confidences.push_back(score);
            Mat mask_conf = output_detect.row(i).colRange(data_detect_shape[1] - data_proto_shape[1], data_detect_shape[1]);
            mask_confs.push_back(mask_conf);
        }
    }
    Mat rgb_mask = Mat::zeros(image.size(), image.type());
    Mat masked_img;
    RNG rng;
    vector<int> indexes;
    dnn::NMSBoxes(boxes, confidences, 0.25, 0.45, indexes);
    for (size_t i = 0; i < indexes.size(); i++) {
        int index = indexes[i];
        int idx = classIds[index];
        rectangle(image, boxes[index], Scalar(0, 0, 255), 2, 8);
        rectangle(image, Point(boxes[index].tl().x, boxes[index].tl().y - 20),
            Point(boxes[index].br().x, boxes[index].tl().y), Scalar(0, 255, 255), -1);
        putText(image, labels[idx], Point(boxes[index].tl().x, boxes[index].tl().y), FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 0), 2, 8);
        Mat m = mask_confs[i] * output_proto;
        for (int col = 0; col < m.cols; col++) {
            m.at<float>(0, col) = sigmoid_function(m.at<float>(0, col));
        }
        Mat m1 = m.reshape(1, 160);
        int x1 = std::max(0, boxes[index].x);
        int y1 = std::max(0, boxes[index].y);
        int x2 = std::max(0, boxes[index].br().x);
        int y2 = std::max(0, boxes[index].br().y);
        int mx1 = int(x1 / x_factor * 0.25);
        int my1 = int(y1 / y_factor * 0.25);
        int mx2 = int(x2 / x_factor * 0.25);
        int my2 = int(y2 / y_factor * 0.25);
        Mat mask_roi = m1(Range(my1, my2), Range(mx1, mx2));
        Mat rm, det_mask;
        resize(mask_roi, rm, Size(x2 - x1, y2 - y1));
        for (int r = 0; r < rm.rows; r++) {
            for (int c = 0; c < rm.cols; c++) {
                float pv = rm.at<float>(r, c);
                if (pv > 0.5) {
                    rm.at<float>(r, c) = 1.0;
                }
                else {
                    rm.at<float>(r, c) = 0.0;
                }
            }
        }
        rm = rm * rng.uniform(0, 255);
        rm.convertTo(det_mask, CV_8UC1);
        if ((y1 + det_mask.rows) >= image.rows) {
            y2 = image.rows - 1;
        }
        if ((x1 + det_mask.cols) >= image.cols) {
            x2 = image.cols - 1;
        }
        Mat mask = Mat::zeros(Size(image.cols, image.rows), CV_8UC1);
        det_mask(Range(0, y2 - y1), Range(0, x2 - x1)).copyTo(mask(Range(y1, y2), Range(x1, x2)));
        add(rgb_mask, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), rgb_mask, mask);
        addWeighted(image, 0.5, rgb_mask, 0.5, 0, masked_img);
    }
    ho_Image_Result = MatToHImage(rgb_mask);
    GenImageConst(&ho_Image, "byte", hv_Width, hv_Height);
    Rgb1ToGray(ho_Image_Result, &ho_GrayImage_Result);
    GetImageSize(ho_Image_Result, &hv_Width_S, &hv_Height_S);
    GenRectangle1(&ho_Rectangle, 0, 0, hv_Height_S - 1, hv_Width_S - 1);
    GetRegionPoints(ho_Rectangle, &hv_Rows, &hv_Cols);
    GetGrayval(ho_GrayImage_Result, hv_Rows, hv_Cols, &hv_Grayvals);
    hv_offset_X = hv_Row_Loc - (hv_Height_S / 2);
    hv_offset_Y = hv_Column_Loc - (hv_Width_S / 2);
    hv_Rows += hv_offset_X;
    hv_Cols += hv_offset_Y;
    SetGrayval(ho_Image, hv_Rows, hv_Cols, hv_Grayvals);
    WriteImage(ho_Image, "bmp", 0, "mask");
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)
project(Halcon-yolov8-seg)
set("OpenCV_DIR" "E:\\Opencv\\opencv_vs\\build")
set("ONNXRUNTIME_DIR" "E:\\Onnxruntime\\cpu\\1.15")
set(OpenCV_INCLUDE_DIRS ${OpenCV_DIR}\\include)
set(OpenCV_LIB_DIRS ${OpenCV_DIR}\\x64\\vc16\\lib)
set(OpenCV_LIB_DEBUG ${OpenCV_DIR}\\x64\\vc16\\lib\\opencv_world480d.lib) 
set(OpenCV_LIB_RELEASE ${OpenCV_DIR}\\x64\\vc16\\lib\\opencv_world480.lib)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(OpenCV QUIET)
set(HALCON_INCLUDE_DIR "E:/Halcon/HALCON-24.05-Progress/include"
                "E:/Halcon/HALCON-24.05-Progress/include/halconcpp")
set(HALCON_LIB_DIR "E:/Halcon/HALCON-24.05-Progress/lib/x64-win64")
include_directories(${OpenCV_INCLUDE_DIRS} ${HALCON_INCLUDE_DIR})
link_directories(${HALCON_LIB_DIR})
add_executable(Halcon-yolov8-seg main.cpp)
target_compile_features(Halcon-yolov8-seg PRIVATE cxx_std_14)
find_library(PATH ${ONNXRUNTIME_DIR})
target_include_directories(Halcon-yolov8-seg PRIVATE "${ONNXRUNTIME_DIR}/include")
target_link_libraries(Halcon-yolov8-seg "${ONNXRUNTIME_DIR}/lib/onnxruntime.lib")
target_link_libraries(Halcon-yolov8-seg 
    $<$<CONFIG:Debug>:${OpenCV_LIB_DEBUG}>
    $<$<CONFIG:Release>:${OpenCV_LIB_RELEASE}>
    halconcpp.lib
)

bus_transform.jpg
mask.bmp


网站公告

今日签到

点亮在社区的每一天
去签到