C# 中的Bitmap 和(c++)opencv之间的传递

2023-05-16

C# 中的Bitmap 和(c++)opencv之间的传递

文章目录

  • C# 中的Bitmap 和(c++)opencv之间的传递
    • 1. C#传递bitmap给C++
    • 2. PixelFormat和opencv Mat类的对应关系
    • 附注

1. C#传递bitmap给C++

  • C++:bitmapTest.cpp 文件代码如下,需要编译成动态库bitmapTest.dll给C#调用
#include <iostream>
#include "opencv.hpp"

#define myExport  extern "C" __declspec(dllexport)
void ShowImage(const cv::Mat  &image, const std::string name, int waitKey=0)
{
	if (image.empty())
		return;

	cv::namedWindow(name, 0);
	cv::imshow(name, image);
	cv::waitKey(waitKey);
}

myExport void APIGetBitmapFromCSharp(uchar * data, int width, int height, int stride)
 {
	 //采用下面的方式初始化一个cv Mat对象后,对这个对象的修改也就是对C#中的bitmap的修改
	 //因为它们使用的数据的内存地址都是一样的
	 cv::Mat img = cv::Mat(cv::Size(width, height), CV_8UC3, data, stride);
	 //or 
	 //cv::Mat img(cv::Size(width, height), CV_8UC3, data, stride);
	 
      //如果在这里转换颜色那么在C#中的图片的颜色也会被转换,如果不想改变原来的图就clone一个新图,在新图上处理
	 //cv::cvtColor(img, img, cv::COLOR_BGR2HSV);
	 ShowImage(img, "image");
 }
  • C#

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
    
    namespace CSharpBitmapAndCPPOpencv
    {
    
        class Program
        {
            
            [DllImport("bitmapTest.dll", CallingConvention = CallingConvention.Cdecl)]
            extern static void APIGetBitmapFromCSharp(IntPtr data, int width, int height, int stride);
           
            static public void SendBitmapToCPP()
            {
                Bitmap img = new Bitmap("K:\\trash\\ROI.bmp");
                BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite,
                    PixelFormat.Format24bppRgb);
                int width = imgData.Width;
                int height = imgData.Height;
                int stride = imgData.Stride;
                try
                {
                    APIGetBitmapFromCSharp(imgData.Scan0, width, height, stride);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                img.UnlockBits(imgData);
                //img.Save("k:\\trash\\ROI_.bmp");
            }
    
            static void Main(string[] args)
            {
                SendBitmapToCPP();
            }
        }
    }
    
    

2. PixelFormat和opencv Mat类的对应关系

  • PixelFormat.Format24bppRgb时对应的opencv是CV_8UC3,颜色通道分别是B,G,R(虽然它标示的是24bppRgb但是在opencv里面用cv::split出来看就知道了它是B,G,R的)

  • PixelFormat.Format32bppPArgb对应CV_8UC4,

  • Format8bppIndexed对应CV_8UC1

    一般只要opencv的Mat类的stride和C#中bitmap图的stride对应上就可以正确解析。

附注

C#中保存的Format8bppIndexed格式的图片并不是像opencv中的CV_8UC1一样是纯的单通道图,而一种类似伪彩图的模式。测试如下,在C#中创建一张全0的8bits的图,在C++中把中间部分填充为255,分别在C++和C#中保存图片

  • C#

    static public void test8BitsImage()
    {
        int w = 100;
        int h = 100;
        int stride = w * 1;
    
        byte[] imgdata = new byte[stride * h];
    
        IntPtr d = Marshal.AllocHGlobal(imgdata.Length);
        Marshal.Copy(imgdata, 0, d, imgdata.Length);
        Bitmap img_8bits = new Bitmap(w,h,stride,PixelFormat.Format8bppIndexed, d);
    
        Rectangle rect = new Rectangle(0, 0, img_8bits.Width, img_8bits.Height);
        BitmapData imgData = img_8bits.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
    
        try
        {
            APIGetBack8BitsImage(imgData.Scan0, w,  h, stride);
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        img_8bits.Save("k:\\trash\\gray.bmp");
    }
    
  • C++

    myExport void APIGetBack8BitsImage(uchar * data, int width, int height, int stride)
    {
    	cv::Mat img = cv::Mat(cv::Size(width, height), CV_8UC1, data, stride);
    
    	uchar * p = NULL;
    	for (int row = img.rows / 4; row <3* img.rows/4; row++)
    	{
    		p = img.ptr<uchar>(row);
    		for (int col = img.cols / 4; col < 3*img.cols/4; col++)
    			*(p + col) = 255;
    	}
    	cv::imwrite("k:\\trash\\gray_opencv.bmp",img);
    
    }
    

    gray.bmp是C#保存的图,gray_opencv.bmp是C++中用opencv保存的图

gray.bmp是C#保存的图,gray_opencv.bmp是C++中用opencv保存的图

图片保存后的信息

image.png

上面两个图存储时大小不一样,用imageJ打开也可以看到在C++中用opencv保存的是8bits的图,在C#中保存的就是一张伪彩图。

在使用上如果不需要保存的话不管什么格式的图片,只要C#中bitmap图的锁存格式和opencv的格式对上:24bpp–>CV_8UC3,32bpp–>CV_8UC4,8Indexed–>CV_8UC1,stride保持一致就不会有什么问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中的Bitmap 和(c++)opencv之间的传递 的相关文章

  • 算数左移、逻辑右移、算数右移、逻辑右移

    算术左移和逻辑左移一样都是右边补0 算术左移 xff08 适用于有符号数 xff09 高位移出 xff0c 低位补0 xff08 要注意数据位最高位为1时极有可能溢出 xff09 比如 0010 1011B 算术左移一位 01010110B
  • java使用ssl连接mysql

    Connecting Securely Using SSL 官方文档 xff0c 演示使用 上面文章里 Setting up Server Authentication 就是在客户端设置认证mysql服务器 xff0c Setting up
  • amd和arm安装ffmpeg踩坑报错处理

    一 amd安装ffmpeg yum安装 系统版本 xff1a CentOS Linux release 7 2 1511 Core 内核版本 xff1a 3 10 0 862 el7 x86 64 1 SMP Fri Apr 20 16 4
  • Powershell常用命令(一)

    Invoke Command xff08 icm xff09 功能 xff1a 在本地或者远程运行命令 xff0c 命令执行的结果 span class token punctuation span 含错误 span class token
  • Ubuntu 突然无法联网,ifconfig 查看仅回环IP时,ping 其他IP显示connect: Network is unreachable的解决方法

    场景 xff1a Ubuntu先前使用时可以联网 xff0c 本地私有ip也存在 xff0c 某次打开Ubuntu后 xff0c 用ifconfig查看IP仅本地的回环ip xff0c ping 别的ip显示connect Network
  • linux命令_复制文件/目录到指定目录下

    复制文件 xff1a 把1 txt 复制到根目录下的sbin目录 cp 43 文件名 xff08 可带路径 xff09 43 目标路径 xff08 带路径 xff09 如 xff1a cp 1 txt sbin 复制目录 xff1a 把re
  • 栈(一本通)

    第一类型 xff1a 车厢调度 进栈顺序是固定的1 2 3 4 xff0c 判断能不能按照给定的顺序出来 include lt iostream gt include lt cstring gt include lt cmath gt in
  • 一本通:1191流感传染

    一本通 xff1a 流感传染 题目描述 有一批易感人群住在网格状的宿舍区内 xff0c 宿舍区为n n的矩阵 xff0c 每个格点为一个房间 xff0c 房间里可能住人 xff0c 也可能空着 在第一天 xff0c 有些房间里的人得了流感
  • CentOS 7 使用iptables 开放端口

    转自 https www cnblogs com kyuang p 6307535 html CentOS 7 0默认使用的是firewall作为防火墙 xff0c 这里改为iptables防火墙 1 关闭firewall xff1a sy
  • 模拟幅度调制系统抗干扰性能仿真分析

    目录 1 引言2 系统模型和仿真1 DSB SC调制和解调1 调制过程2 解调过程3 信噪比分析4 matlab代码 2 AM调制和解调1 调制过程2 解调过程 xff1a 3 信噪比分析4 matlab代码 3 SSB调制和解调1 调制过
  • 解决重启后 /mnt/hgfs下共享文件夹挂载失效问题

    问题描述 xff1a 如题 xff0c 在 mn hgfs 下使用ls命令不显示共享文件夹 xff0c 在root权限下运行命令 xff1a vmhgfs fuse host mnt hgfs 后重新进入目录显示共享文件夹 xff0c 重启
  • Matlab安装硬件支持包补充@水月流荧

    您好 xff0c 请问我按照文章内容下载了支持包 xff0c 并且将archive拷贝到E matlab bin win64 xff08 本机位置 xff09 中 xff0c 后在win64中找到SupportSoftwareInstall
  • spring-boot-maven-plugin未指定版本导致的编译错误

    spring boot maven plugin未指定版本导致的编译错误 报错 springboot应用在使用maven编译时会报如下错误 xff1a Java Runtime class file version 61 0 this ve
  • ssh连接Centos7时vim无法使用粘贴板原因及解决方法

    原因 xff1a 1 命令行的vim没有 43 和 两个寄存器 xff08 原因之一 xff09 xff0c 退出vim后粘贴板内容不会保留到vim所在系统的粘贴板 2 在有 43 和 寄存器的前提下 xff0c 可以从vim复制到vim所
  • >Error:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details

    gt Error com android tools aapt2 Aapt2Exception AAPT2 error check logs for details 这个错误会在3 0里面出现 解决办法是在gradle properties
  • 一键部署k8s脚本

    一键部署k8s脚本 目录 一键部署k8s脚本前情提示环境准备硬件系统要求角色说明 xff1a 其余准备工作 centos准备centos网络准备centos软件准备 部署k8s前配置下载部署脚本安装 Ansible 运行环境修改安装的配置文
  • Docker in docker 实现

    Docker in docker 文章目录 Docker in docker原理实现 xff08 centos7 xff09 常见问题参考 在docker容器内运行docker一般是不被倡导的 但有些场景和业务上 xff0c 需要在容器内使
  • 一篇文章入门spring

    Spring入门1 在之前我们对象的创建都是我们自己new出来的 xff0c 比如Student stu 61 new Student xff08 xff09 但是我们现在有了spring 我们将对象的创建的工作交给spring来处理 那么
  • JAVA数据结构之数组详细教程

    本文整理了java数据结构的数组操作 希望对刚入门数据结构的同志们有帮助 java数组非常简单 只要有JAVA语言基础就可以看这篇博文 大家不要害怕 非常简单 整理博客真的很花费时间 xff0c 如果对大家有帮助 xff0c 麻烦点赞评论
  • JAVA程序(MongoTemplate)操作mongodb数据库常用方法(超级详细)

    这里使用的是Spring 43 MongoTemplate来操作mongodb数据库 如果有不了解spring的同志先去了解一下spring为好 xff0c 这里给出实现的一些方法 主要有 xff1a 查询 增加 修改 删除 多字段增加 模

随机推荐

  • template操作mongodb数据库(更新方法大全)

    本文是使用JAVA程序操作MongoDB数据库 里面提供了各种更新数据的方法 xff0c 查询的各种方法会在后面进行更新 本文只是提供了数据库更新操作的一些方法 数据库数据和字段如下 xff1a 对于更新数据 xff0c 我将更新数据的方法
  • mongodb template 计算mongodb日期的解决方案

    mongodb由于特殊的日期格式 存在 8时区的问题 所以在使用java程序解决日期计算问题就会有点麻烦 其实也很简单 就是先将日期改变时区 然后转成带有格式String类型的日期 然后在java里面的将String转化成date类型即可
  • 一篇文章彻底理解二分搜索树(附代码实现)

    本文使用JAVA语言进行描述 其实本质上什么语言描述数据结构都是可以的 二叉树基础 二叉树的根节点 二叉树递归结构 xff1a 上面是一个满二叉树 但是实际中也有二叉树不是满的 二分搜索树 二分搜索树也不一定是满的 所以使用二分搜索树需要具
  • opengl 源码分析常见问题

    Opengl 一些问题解答 为什么opengl 不能跨线程 大家有没有想过这个问题 xff0c 网上给出的答案其实看得不太明白 xff0c 接下来我们看源码让你知道 C EGLContext Display createContext EG
  • mongodbtamplate使用程序创建mongdb索引的解决方案

    话不多说 xff0c 直接上代码 xff1a span class token keyword public span span class token keyword boolean span span class token funct
  • el表达式取不到值

    在jsp页面中有可能出现el表达式取不到值的问题 xff0c 但是反复检查代码 xff0c 跑断点都没有问题 xff0c 这是因为jsp忽略了el表达式 所以只要加上下面一行代码就可以了 span class token operator
  • Kaggle心脏病数据集为例学习机器学习的可解释性分析

    需要安装的工具包 pip install numpy pandas matplotlib seaborn wheel pandas profiling jupyter notebook span class token operator s
  • readlink /var/lib/docker/overlay2: invalid argument的解决方案

    发生这种情况是因为在运行Docker映像之间重新启动了docker xff0c 该映像已损坏 我重新启动系统 xff0c 然后运行以下命令 docker compose build no cache docker compose up 您还
  • python调用IP摄像头

    利用RTSP 43 opencv就可以实现网络摄像头的调用 rtsp是实时流传输协议 xff0c 是基于TCP IP协议体系中的一个应用层协议 xff0c 可以控制声音或者影像的多媒体串流协议 但是不同品牌的摄像头有不同的RTSP地址 下面
  • 22岁-时光如河,浮生为鱼

    时光如河 xff0c 浮生为 x1f41f 还没有学会告别 xff0c 四年就这样悄悄过去了 如往年今日一样 xff0c 依旧写些懒懒散散的文字致敬这一年的时光 x1f495 22岁生日快乐 x1f495 全文约4200字 xff0c 阅读
  • 电子书下载网站汇总

    网站名称地址简介语言推荐指数备注Book4Uhttp www book4you sk 外文下载网站斯洛伐克语 BookYardshttps www bookyards com en welcome主要面向教师的门户网站 xff0c 其中的书
  • Docker版 E5续订的E5调用API续订服务:Microsoft 365 E5 Renew X

    本文是基于作者SundayRX提出的E5 调用API续订服务 xff1a Microsoft 365 E5 Renew X的基础上提出的Docker版本的E5调用API续订服务 基础的账号注册等过程见SundayRX的博客 xff1a 账号
  • Docker版 Linux百度网盘备份工具

    一些必须要知道的事 xff1a 这个镜像的主要目的是为了将服务器或者群晖等linux场景中的资料备份到百度网盘中容器的基础镜像为ubuntu镜像 容器的备份周期为每天的凌晨两点 具体步骤如下 xff1a 下载镜像 docker pull h
  • 操作系统(五)中断和异常

    1 5 中断和异常 在上节内核态与用户态的转换过程中曾经提到过 xff0c 操作系统会响应中断信号强制夺回CPU使用权 xff0c 使用户态转换为内核态 中断 是操作系统夺回CPU使用权的唯一方式 xff0c 如果没有 中断 机制 xff0
  • Mediacodec 如何硬件解码到纹理的

    Mediacodec 如何硬件解码到纹理的 背景 xff1a 网上很多关于mediacodec xff0c surface xff0c surfacetexture的源码分析 xff0c 以及内部原理 xff0c 但是都局限于各自的内容 x
  • pyinstaller 递归深度设置(A RecursionError occurred)

    简介 xff1a pyinstaller常用于打包python文件 xff0c 当导入的包过多时常会出现一个递归深度超过限制的错误 这个可以通过设置最大递归深度来解决 1 pyinstaller报错信息 61 61 61 61 61 61
  • labelme标注格式转coco格式

    摘要 xff1a labelme是广泛使用的深度学习标注工具 xff0c 支持目标检测和实例分割等任务的标注 xff0c 但是一些框架如detectron2 xff0c solo等需要的是coco格式的 xff0c 这里提供一个示例把lab
  • opencv C++ 旋转任意角度图片

    摘要 xff1a opencv里面似乎没有直接的旋转图片的接口 xff0c 这里实现一个旋转任意角度的方法 xff0c 在旋转的时候调用opencv里面的仿射变换函数实现 有两种旋转模式 xff1a 一种按图片中心旋转 xff0c 尺寸与原
  • C++ opencv曲线拟合

    简介 xff1a 此问题是在做旋转模板匹配的时候 xff0c 选择最好的匹配结果时产生的 查找资料发现多项式拟合问题可以变成一个超定方程的求解问题 xff0c 而opencv中本身有一个cv solve 函数可以求解线性方程组 xff0c
  • C# 中的Bitmap 和(c++)opencv之间的传递

    C 中的Bitmap 和 xff08 c 43 43 xff09 opencv之间的传递 文章目录 C 中的Bitmap 和 xff08 c 43 43 xff09 opencv之间的传递1 C 传递bitmap给C 43 43 2 Pix