WiTiAi 发表于 2024-4-16 20:26:35

Halide与opencv混编

Halide与opencv混编:
【1】C#代码
// See https://aka.ms/new-console-template for more information
using OpenCvSharp;
using System.Runtime.InteropServices;
using ConsoleApp1;
using System;

void printhello()
{
    Console.WriteLine("Hello, World!");
}
printhello();
int a = 42;
int b = 119;
int c = a + b;
Console.WriteLine(c);

string imagepath = @"C:\\AIOCRProjects\\Image\\1 (1).jpg";
Mat src = Cv2.ImRead(imagepath, ImreadModes.Grayscale);
// 获取灰度图像的宽度、高度和每像素的字节数
int width = src.Cols;
int height = src.Rows;
int bytesPerPixel = src.ElemSize1();

// 计算图像数据的总字节大小
CallAIDLL.BlurHal2_test(src.Width, src.Height, src.Channels(), src.Data);
// 锁定Mat对象以获取其数据指针
Console.WriteLine(src.Channels());
Console.WriteLine("done");

Mat ColorMat = Cv2.ImRead(imagepath, ImreadModes.Color);
var bytes = new byte;//这里必须乘以通道数,不然数组越界,也可以用w*h*c,差不多
//var bytes = new byte;//这里必须乘以通道数,不然数组越界,也可以用w*h*c,差不多
//Console.WriteLine(ColorMat.Total() * 3);
//Console.WriteLine(ColorMat.Width * ColorMat.Height * ColorMat.Channels());
Marshal.Copy(ColorMat.Data, bytes, 0, bytes.Length);
IntPtr p0 = Marshal.AllocHGlobal(ColorMat.Width * ColorMat.Height * ColorMat.Channels());
Marshal.Copy(bytes, 0, p0, ColorMat.Width * ColorMat.Height * ColorMat.Channels());
Console.WriteLine(ColorMat.Channels());
Console.WriteLine(ColorMat.Width);
Console.WriteLine(ColorMat.Height);
CallAIDLL.BlurHal2_test(ColorMat.Width, ColorMat.Height, ColorMat.Channels(), p0);

Console.ReadKey();【2】C++代码:
Halide::Func AIpredict::BlurWiti3(Halide::Param<int32_t> aWidth, Halide::Param<int32_t> aHeight, Halide::Param<int32_t> aChannel, Halide::ImageParam input)
{
      //Mat inputMat = Intptr2Mat(aWidth, aHeight, aChannel, aBytes); // 灰度图像
      //Halide::Buffer<uint8_t> input = Mat2Buffer(inputMat);         // GrayImage
      Halide::Var x, y, c;
      Halide::Func clamped;
      Halide::Expr clamped_x = Halide::clamp(x, 0, input.width() - 1);
      Halide::Expr clamped_y = Halide::clamp(y, 0, input.height() - 1);
      //std::cout << "image cols: " << input.dimensions() << std::endl;
      //if (aChannel.get() == 3)
      //{
                input.dim(0).set_stride(3);   // stride in dimension 0 (x) is three
                input.dim(2).set_stride(1);   // stride in dimension 2 (c) is one
                input.dim(2).set_bounds(0, 3);// Dimension 2 (c) starts at 0 and has extent 3.
      //}
      clamped(x, y, c) = input(clamped_x, clamped_y, c);
      Halide::Func input_16;
      input_16(x, y, c) = cast<uint16_t>(clamped(x, y, c));
      Halide::Func blur_x;
      blur_x(x, y, c) = (input_16(x - 1, y, c) + 2 * input_16(x, y, c) + input_16(x + 1, y, c)) / 4;
      Halide::Func blur_y;
      blur_y(x, y, c) = (blur_x(x, y - 1, c) + 2 * blur_x(x, y, c) + blur_x(x, y + 1, c)) / 4;
      //Buffer<uint8_t> result = output.realize({ input.width(), input.height() });// GrayImage
      //Mat output_image_last = Buffer2Mat(result);
      //return (Mat2UnsignedChar(output_image_last));

      // Schedule
      //blur_x.compute_root().vectorize(x, 8).parallel(y);
      //blur_y.compute_at(blur_x, y).vectorize(x, 8);

      Halide::Func output;
      output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));

      output.compile_jit();
      return output;
}
Halide::Func AIpredict::BlurWiti2(Halide::Param<int32_t> aWidth, Halide::Param<int32_t> aHeight, Halide::Param<int32_t> aChannel, Halide::ImageParam input)
{
      //Mat inputMat = Intptr2Mat(aWidth, aHeight, aChannel, aBytes); // 灰度图像
      //Halide::Buffer<uint8_t> input = Mat2Buffer(inputMat);         // GrayImage
      Halide::Var x, y, c;
      Halide::Func clamped;
      Halide::Expr clamped_x = Halide::clamp(x, 0, input.width() - 1);
      Halide::Expr clamped_y = Halide::clamp(y, 0, input.height() - 1);
      //std::cout << "image cols: " << input.dimensions() << std::endl;
      //if (aChannel.get() == 3)
      //{
      //input.dim(0).set_stride(3);   // stride in dimension 0 (x) is three
      //input.dim(2).set_stride(1);   // stride in dimension 2 (c) is one
      //input.dim(2).set_bounds(0, 3);// Dimension 2 (c) starts at 0 and has extent 3.
      //}
      clamped(x, y, c) = input(clamped_x, clamped_y, c);
      Halide::Func input_16;
      input_16(x, y, c) = cast<uint16_t>(clamped(x, y, c));
      Halide::Func blur_x;
      blur_x(x, y, c) = (input_16(x - 1, y, c) + 2 * input_16(x, y, c) + input_16(x + 1, y, c)) / 4;
      Halide::Func blur_y;
      blur_y(x, y, c) = (blur_x(x, y - 1, c) + 2 * blur_x(x, y, c) + blur_x(x, y + 1, c)) / 4;
      //Buffer<uint8_t> result = output.realize({ input.width(), input.height() });// GrayImage
      //Mat output_image_last = Buffer2Mat(result);
      //return (Mat2UnsignedChar(output_image_last));

      // Schedule
      //blur_x.compute_root().vectorize(x, 8).parallel(y);
      //blur_y.compute_at(blur_x, y).vectorize(x, 8);

      Halide::Func output;
      output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));

      output.compile_jit();
      return output;
}

void AIpredict::BlurHal2_test(int aWidth, int aHeight, int aChannel, unsigned char* aBytes)
{
      //cv::Mat inputMat2;
      //inputMat2 = inputMat.clone();
      Halide::Param<int32_t> WidthHal;
      Halide::Param<int32_t> HeightHal;
      Halide::Param<int32_t> ChannelHal;
      Halide::ImageParam GrayHal(type_of<uint8_t>(), 3);// third channel = 1
      //Halide::ImageParam RGBHal(type_of<uint8_t>(), 3); // third channel = 3
      if (aChannel == 1)
      {
                BlurWiti_Pipeline = BlurWiti2(WidthHal, HeightHal, ChannelHal, GrayHal);
      }
      else
      {
                BlurWiti_Pipeline = BlurWiti3(WidthHal, HeightHal, ChannelHal, GrayHal);
      }

      cv::Mat inputMat;
      inputMat = Intptr2Mat(aWidth, aHeight, aChannel, aBytes);
      /*std::cout << "image channel: " << inputMat.channels() << std::endl;
      std::cout << "image dims: " << inputMat.dims << std::endl;
      cv::imwrite("D:\\230.jpg", inputMat);
      cv::Mat inputMat2;
      inputMat2 = cv::imread("C:\\AIOCRProjects\\Image\\1 (1).jpg", 1);
      std::cout << "image channel: " << inputMat2.channels() << std::endl;
      std::cout << "image dims: " << inputMat2.dims << std::endl;*/

      Halide::Buffer<uint8_t> input = Mat2Buffer(inputMat); // GrayImage, default dimension = 3
      //Halide::Buffer<uint8_t> input = Halide::Runtime::Buffer<uint8_t>::make_interleaved(aBytes, aWidth, aHeight, aChannel);
      //Halide::Buffer<uint8_t> input2 = load_image("C:\\AIOCRProjects\\Image\\1 (1).jpg"); // GrayImage
      //std::cout << "image channel: " << input.channels() << std::endl;
      //std::cout << "image dimensions: " << input.dimensions() << std::endl;
      //std::cout << "image channel: " << input2.channels() << std::endl;
      //std::cout << "image dimensions: " << input2.dimensions() << std::endl;
      //Halide::Buffer<uint8_t> input3 = input(:, : , 0);
      //Halide::Tools::save_image(input, "D:\\brighter.png");

      //Halide::Buffer<uint8_t> input = load_image("D:\\brighter.png"); // GrayImage
      //input = Halide::Tools::load_image("D:\\brighter.png"); // GrayImage

      WidthHal.set(aWidth);
      HeightHal.set(aHeight);
      ChannelHal.set(aChannel);
      GrayHal.set(input);

      //std::cout << "image cols: " << input.width() << std::endl;
      //std::cout << "image rows: " << input.height() << std::endl;
      //std::cout << "image channel: " << input.channels() << std::endl;

      Halide::Buffer<uint8_t> output(aWidth, aHeight, aChannel);
      BlurWiti_Pipeline.realize(output);

      cv::Mat outImage = Buffer2Mat(output);
      cv::imwrite("D:\\23.jpg", outImage);
      //return Buffer2Mat(output);
}







页: [1]
查看完整版本: Halide与opencv混编