如何在c#中使用opencv函数库

这个demo用c#实现图片裁剪和半透明融合的功能演示程序。功能挺简单的,就是把一张固定大小的图片先做边缘羽化,然后贴到一个圆形泡泡形状的底图上,最后把结果半透明融合到一张背景图上。

C#实现图像的羽化、将图片裁剪复制到一个圆形图片这些都挺简单的,最后一步融合到背景图上需要用到opencv的seamlessClone方法。网上搜索c#使用opencv的方法有很多,一种是直接使用opencv的C#版本,一种是先把opencv的方法封装到一个dll然后用c#调用这个dll导出的方法。对于我这个需求,后一种方法最合算了。我只用到了一个方法而已。vc中怎么使用opencv就不说了,直接开始吧。

用VC创建一个win32项目,选择生成dll动态链接库。

添加一个cpp文件:

// opencvImage.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include "opencv2/photo.hpp"

#ifdef _DEBUG
#pragma comment(lib,"opencv_core331d.lib")
#pragma comment(lib,"opencv_imgproc331d.lib")
#pragma comment(lib,"opencv_photo331d.lib")
#else
#pragma comment(lib,"opencv_core331.lib")
#pragma comment(lib,"opencv_imgproc331.lib")
#pragma comment(lib,"opencv_photo331.lib")
#endif

#define Export_API extern "C" _declspec(dllexport)

using namespace cv;

Export_API void _stdcall Blend(unsigned char * src, int width, int height, int stride,
							 int bitcount, unsigned char *dst, int alpha)
{
	double beta,alpha1 = alpha / 255.0 ;
	Mat src1(width, height, CV_8UC3, src, stride);
	Mat src2(width, height, CV_8UC3, dst, stride);
	Mat dst1(width, height, CV_8UC3, dst, stride);

	beta = (1.0 - alpha1);

	addWeighted(src1, alpha1, src2, beta, 0.0, dst1);
}

Export_API void _stdcall PoissonBlend(unsigned char * src, int width, int height, int stride,
									 int bitcount, unsigned char *dst, int flags)
{
	int cx = width >> 1;
	int cy = height >> 1;
	int numpts = 5;
	Point point(cx, cy);
	Point pts[] = { { 80, 40 }, { 30, height - 80 }, { cx, height - 20 }, { width - 30, height - 80 }, { width - 80, 40 } };
	Mat img0(width, height, CV_8UC3, src, stride);
	Mat dst0(width, height, CV_8UC3, dst, stride);
	Mat final = Mat::zeros(img0.size(), CV_8UC3);
	Mat mask = Mat::zeros(img0.size(), CV_8UC1);
	const Point* pts4[1] = { &pts[0] };
	fillPoly(mask, pts4, &numpts, 1, Scalar(255, 255, 255), 8, 0);
//	circle(mask, point, cx - 30, Scalar(255, 255, 255),-1);
	bitwise_and(img0, img0, final, mask);
	seamlessClone(img0, dst0, mask, point, dst0, flags);
}

由于使用了_stdcall,所以还需要一个def文件,否则导出函数名字前面有个下划线,_Blend

加一个def文件:

LIBRARY "opencvImage"

EXPORTS

Blend @1

PoissonBlend @2

C#调用方法:

1. 在cs文件开头添加

using System.Runtime.InteropServices;

2.在用到的地方添加

[DllImport("opencvImage.dll")]
unsafe public static extern void Blend(byte* src, int width, int height, int stride, int bitcount, byte* dst, int alpha);

3.调用dll方法

Bitmap bp = new Bitmap(srcImage);

System.Drawing.Rectangle rect = new System.Drawing.Rectangle(x, y, width, height);

BitmapData src = bp.LockBits(rect, ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
Bitmap dp = new Bitmap(destImage);
System.Drawing.Rectangle dstRect = new System.Drawing.Rectangle(dx, dy, width, height);
BitmapData dst = dp.LockBits(dstRect, ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);

int nPitch = src.Stride;
int bitCount = 3;
byte* lpsrc = (byte*)src.Scan0;
byte* lpdst = (byte*)dst.Scan0;
byte alpha = 128;
Blend(lpsrc, width, height, nPitch, bitCount ,lpdst, alpha);
bp.UnlockBits(src);
dp.UnlockBits(dst);
return dp;

最后说明一下

1.VC编译的dll需要放到C#可执行程序的目录下,也就是bin目录下的debug或release目录下,否则会提示一些错误。dll的依赖库也需要放进来,比如我用到了opencv_core331.dll opencv_imgproc331.dll opencv_photo331.dll三个库。

2.如果C#程序不需要用到opencv的对象,可以直接传递指针给dll,这样使用起来很方便。就像下面这样:

Export_API void _stdcall Blend(unsigned char * src, int width, int height, int stride,
							 int bitcount, unsigned char *dst, int alpha)
{
	double beta,alpha1 = alpha / 255.0 ;
	Mat src1(width, height, CV_8UC3, src, stride);
	Mat src2(width, height, CV_8UC3, dst, stride);
	Mat dst1(width, height, CV_8UC3, dst, stride);

	beta = (1.0 - alpha1);

	addWeighted(src1, alpha1, src2, beta, 0.0, dst1);
}

3.很多人说c#调用opencv封装的dll会遇到内存泄漏方面的问题,我觉得如果不用opencv的对象,内存申请和释放都在c#中完成,只是传递指针给opencv做处理,应该没问题。

以上就是如何在c#中使用opencv的详细内容,更多关于c#中使用opencv的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#使用OpenCV剪切图片中的人物头像的实现方法

    前言 本文主要介绍如何使用OpenCV剪切图形中的人物头像. 准备工作 首先创建一个Wpf项目--OpenCV_Face_Wpf,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.CV],如下图. 这里的Emgu.CV选择4.3.0.3890版本,然后安装Emgu.CV和Emgu.CV.runtime.windows. 然后下载所需文件haarcascade_frontalface_default.xml. 可以去OpenCV的开源代码中下载,下载地址:https:/

  • C#使用OpenCV剪切图像中的圆形和矩形的示例代码

    前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.CV],如下图. 这里的Emgu.CV选择4.3.0.3890版本,然后安装Emgu.CV和Emgu.CV.runtime.windows. 使用OPenCV剪切矩形 现在,我们进入项目,进行OPenCV的调用. 首先引入命名空间,如下: using Emgu.CV; using Emgu.CV.Cv

  • C#使用opencv截取旋转矩形区域图像的实现示例

    前言:最近在工程中需要用到截取RotatedRect中的图形,保存为Mat做后续处理.发现opencv文档中没有这个api,最开始想到的方案是将整张图片进行相应的旋转,然后再从中截取正矩形,但是我们要获取的是部分区域,将整张图片进行旋转会造成很多的资源浪费.所以需要自行实现一个旋转矩形的方案. 实现方法 原理是利用向量空间变换,如图 通过 Point2f[] points=rotatedRect.Points(); 可获取RotatedRect四个端点的坐标.先选定一个点为输出Mat左上端点,这

  • C#调用OpenCV开发简易版美图工具【推荐】

    前言 在C#调用OpenCV其实非常简单,因为C#中有很多OPenCV的开源类库. 本文主要介绍在WPF项目中使用OpenCVSharp3-AnyCPU开源类库处理图片,下面我们先来做开发前的准备工作. 准备工作 首先,我们先创建一个WPF项目. 然后,在Nuget上搜索OpenCVSharp,如下图: 接着,我们选择OpenCVSharp3-AnyCPU选项进行安装 . 安装了OpenCVSharp3-AnyCPU后,我们的项目会自动引入4个类库,如下图: 到这里,我们的准备工作就完成了,非常

  • 如何在c#中使用opencv函数库

    这个demo用c#实现图片裁剪和半透明融合的功能演示程序.功能挺简单的,就是把一张固定大小的图片先做边缘羽化,然后贴到一个圆形泡泡形状的底图上,最后把结果半透明融合到一张背景图上. C#实现图像的羽化.将图片裁剪复制到一个圆形图片这些都挺简单的,最后一步融合到背景图上需要用到opencv的seamlessClone方法.网上搜索c#使用opencv的方法有很多,一种是直接使用opencv的C#版本,一种是先把opencv的方法封装到一个dll然后用c#调用这个dll导出的方法.对于我这个需求,后

  • 详解如何在pyqt中通过OpenCV实现对窗口的透视变换

    窗口的透视变换效果    当我们点击Win10的UWP应用中的小部件时,会发现小部件会朝着鼠标点击位置凹陷下去,而且不同的点击位置对应着不同的凹陷情况,看起来就好像小部件在屏幕上不只有x轴和y轴,甚至还有一个z轴.要做到这一点,其实只要对窗口进行透视变换即可.下面是对Qt的窗口和按钮进行透视变换的效果: 具体代码    1.下面先定义一个类,它的作用是将传入的 QPixmap 转换为numpy 数组,然后用 opencv 的 warpPerspective 对数组进行透视变换,最后再将 nump

  • 如何在C#中使用OpenCV(GOCW使用教程)

    1.什么是GOCW 为了解决在Csharp下编写OpenCV程序的问题,我做过比较深入的研究,并且实现了高效可用的方法GreenOpenCsharpWrapper(GOCW).通过这种方法,能够分离界面和算法业务,高效率完成算法调用,而且非常方便进行算法维护.应该说是我在多年项目实践中不断总结提炼出来的一点东西.        GOCW的发布地址为:https://gitee.com/jsxyhelu2020/gocw 2.GOCW有什么特点 分离界面和算法业务 图像数据直接通过内存传值,高效率

  • 教你如何在pycharm中安装opencv,tensorflow,keras

    目录 一.首先安装Anaconda,python和pycharm 二.首先安装opencv 三.安装tensorflow和kerass 四.小结 我在安装环境的时后,怎么都装不上去,搞了好久,现在来写一下心得. 一.首先安装Anaconda,python和pycharm 有很多教程,我就不在此赘述 二.首先安装opencv 1.点击左下角的Terminal 2.输入pip install opencv-python,然后按键盘上的enter(亲测有效) 3.看到successfully就说明安装

  • 详解python中的Turtle函数库

    python对函数库的引用方式 1.import <库名> 例如:import turtle 如果需要使用库函数中的函数,需要使用:<库名>.<函数名> 例如: import turtle turtle.fd(100) 2.from <库名> import <函数名> from <库名> import  *, 使用这种方式时,直接使用<函数名> 例如:  >>>from turtle import *  

  • 如何在Python 中使用 join() 函数把列表拼接成一个字符串

    目录 1.设置 end=’’ 2.拼接字符串(string) 3.举例 内容概要:如何把列表中的元素拼接为一个字符串呢?本文介绍了采用 join() 函数的解决方法. 问题:有一个列表,比如:letters=[‘a’,‘b’,‘c’],想要把列表的元素连续显示出来,应该怎么办? 解决办法: 1.设置 end=’’ 如何使Python中的print()语句运行结果不换行 的方法,设置 end=’’. 如下代码所示: letters=['a','b','c'] for letter in lette

  • 如何在Python 中使用 join() 函数把列表拼接成一个字符串

    目录 1.设置 end=’’ 2.拼接字符串(string) 3.举例 内容概要:如何把列表中的元素拼接为一个字符串呢?本文介绍了采用 join() 函数的解决方法. 问题:有一个列表,比如:letters=[‘a’,‘b’,‘c’],想要把列表的元素连续显示出来,应该怎么办? 解决办法: 1.设置 end=’’ 如何使Python中的print()语句运行结果不换行 的方法,设置 end=’’. 如下代码所示: letters=['a','b','c'] for letter in lette

  • 如何在AngularJs中调用第三方插件库

    在AngularJs中我们会不可避免的使用第三方库,例如jquery插件库.我们不能散乱的在AngularJS中引入这些库,例如在controller中.那么应该怎么在Angular中使用第三方库呢? 如何使用? 很简单,给插件写一个directive. 在这里,我会使用一个简单的jquery插件Toolbar.js 的DEMO. 这是我们如何在jquery中创建一个tooltip的: <!-- Click this to see a toolbar --> <div id="

  • Lua中的常用函数库汇总

    lua库函数 这些函数都是Lua编程语言的一部分, 点击这里了解更多. assert(value) - 检查一个值是否为非nil, 若不是则(如果在wow.exe打开调试命令)显示对话框以及输出错误调试信息 collectgarbage() - 垃圾收集器. (新增于1.10.1) date(format, time) - 返回当前用户机器上的时间. error("error message",level) - 发生错误时,输出一条定义的错误信息.使用pcall() (见下面)捕捉错误

  • WAMP环境中扩展oracle函数库(oci)

    同事昨天接到一个任务,要用php处理oracle数据库的内容,但是php打开oracle扩展不是像mysql那样直接用就行,需要下一点东西才能打开 第一步 需要到oracle官方下载一个install client 包,在win下找到你对应系统版本的zip(注意这里是系统版本) 截止到2015-06-25,下载地址如下http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 例如选择

随机推荐