百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

C# 中使用 OpenCV

bigegpt 2024-08-06 11:48 8 浏览

一、什么是GOCW


为了解决在C#下编写OpenCV程序的问题,我做过比较深入的研究,并且实现了高效可用的方法GreenOpenCsharpWrapper(GOCW)。通过这种方法,能够分离界面和算法业务,高效率完成算法调用,而且非常方便进行算法维护。应该说是我在多年项目实践中不断总结提炼出来的一点东西。


GOCW的发布地址为:https://gitee.com/jsxyhelu2020/gocw


二、GOCW有什么特点


  • 分离界面和算法业务
  • 图像数据直接通过内存传值,高效率完成算法调用
  • 直接编写C++语法程序,方便维护改进
  • 在C#中可以通过CLR方式引用,提供函数级别接口
  • 开放源代码


三、GOCW在VS中的环境配置


下载gocw_master,解压后获得两个目录文件。



其中,GOCW是类库文件,而WINFORM_DEMO是引用范例。


使用VS2017或者更高版本打开WINFORM_DEMO.sln(或新建winform程序),在“引用”处添加GOCW的引用。



特别需要注意,正确编译GOCW需要OpenCV的正确配置,所以需要正确设置include和lib,并且保证对应版本的dll文件能够被正确访问。




特别需要注意1:保证dll和csharp程序的.net目标框架是一致的




特别需要注意2:


  • 保证dll和csharp程序的.net目标框架是一致的
  • 配置管理器中,所有项目版本全部使用64位



四、测试代码


可以直接参考 WINFROM_DEMO



添加GOCW的头文件


using GOCW;


编写GOCW调用代码,你也可以根据需要吧Client的定义放在Form中。你实际使用过程中需要修改lena的地址。


private void button1_Click(object sender, EventArgs e)
{
    Bitmap bmp = (Bitmap)Bitmap.FromFile("e:/template/lena.jpg");
    GOCWClass client = new GOCWClass();
    //调用图像处理算法
    MemoryStream ms = new MemoryStream();
    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    byte[] bytes = ms.GetBuffer();
    Bitmap bitmap = client.testMethod(bytes);
    pictureBox1.Image = bitmap;
}


可以看到,实现了"灰度"变化。



五、原理简介


GOCW是通过CLR的方式进行调用,关于CLR的原理这里不展开。重点将一下你在哪里添加图像处理算法,打开 GOCW.h文件


#pragma once
#include "opencv.hpp"
#using <system.drawing.dll>
using namespace System;
using namespace System::Data;
using namespace System::IO;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace std;
namespace GOCW {
    public ref class GOCWClass
    {
      public:
      /////例子函数//////
      //1.传递图像
      /*  MemoryStream ms = new MemoryStream();
        b.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        byte[] bytes = ms.GetBuffer();
        Bitmap bitmap = client.testMethod(bytes);*/
        Bitmap^  GOCWClass::testMethod(cli::array<unsigned char>^ pCBuf1);
        //2.引用传递int
        /*unsafe
        {
          int* value = stackalloc int[1];
          value[0] = 0;
          int iret = client.allTest(2, 3, value);
        }*/
        int GOCWClass::allTest(int a, int b, int* c);
        //3.引用传递字符串
        System::String^ GOCWClass::allTestStr(System::String^ inputStr);
        /////业务函数//////
        /*unsafe
        {
            int* value = stackalloc int[1];//返回代码
            value[0] = 0;
            bitmap = client.fetchresult(bytes, value);//调用来自GOClrClasslibrary图像处理算法
            if (value[0] == 0)//0真1假
            {
                res = true;
            }
            else
            {
                res = false;
            }
        }*/
        Bitmap^  GOCWClass::fetchresult(cli::array<unsigned char>^ pCBuf1, int* errorCode);
    };
}


这里以"三明治"的方法将各种实现的方法进行了申明,具体的实现在GOCW.cpp中,比如我们举一个例子。


//1.传递图像
Bitmap^  GOCWClass::testMethod(cli::array<unsigned char>^ pCBuf1)
{
    ////////////////////////////////将输入cli::array<unsigned char>转换为cv::Mat/////////////////////////
    pin_ptr<System::Byte> p1 = &pCBuf1[0];
    unsigned char* pby1 = p1;
    cv::Mat img_data1(pCBuf1->Length, 1, CV_8U, pby1);
    cv::Mat img_object = cv::imdecode(img_data1, cv::IMREAD_UNCHANGED);
    if (!img_object.data)
        return nullptr;
    ////////////////////////////////////////////OpenCV的算法处理过程////////////////////////////////////
    Mat draw = img_object.clone();
    cvtColor(draw, draw, COLOR_BGR2GRAY);
    cvtColor(draw, draw, COLOR_GRAY2BGR);
    /////////////////////////将cv::Mat转换为Bitmap(只能传输cv_8u3格式数据)///////////////////////////////
    if (!draw.data)
        return nullptr;
    Bitmap^ bitmap = MatToBitmap(draw);
    return bitmap;
}


在这段代码中


Mat draw = img_object.clone();
cvtColor(draw, draw, COLOR_BGR2GRAY);
cvtColor(draw, draw, COLOR_GRAY2BGR);


是具体业务函数,可以根据实际算法要求进行修改。关于参数的传入传出,在其他几个函数中都有说明。


六、初步小结


虽然GOCW相比较OpenCVSharp复杂一点,但是它能够和现有系统更紧密结合,优势也非常明显。如果你首先是图像处理开发者,需要为算法寻找一个可以运行的平台,那么GOCW基于CLR的封装形式,肯定更适合你!

相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...