多曝光融合OpenCV4.8 CLR与C#混合开发

多曝光融合OpenCV4.8 CLR与C#混合开发

使用CLR混合开发更加契合现在的项目,话不多说,直接上代码,CLR与c#开发网上很多教程,c++配置opencv也有很多教程,文后做个简单的介绍

第一部分:bitmap转mat

Mat BitmapToMat(System::Drawing::Bitmap^ bmp)
{
	IplImage* tmp;

	System::Drawing::Imaging::BitmapData^ bmData = bmp->LockBits(System::Drawing::Rectangle(0, 0, bmp->Width, bmp->Height), System::Drawing::Imaging::ImageLockMode::ReadOnly, bmp->PixelFormat);
	if (bmp->PixelFormat == System::Drawing::Imaging::PixelFormat::Format8bppIndexed)
	{
		tmp = cvCreateImage(cvSize(bmp->Width, bmp->Height), IPL_DEPTH_8U, 1);
		tmp->imageData = (char*)bmData->Scan0.ToPointer();
	}
	else if (bmp->PixelFormat == System::Drawing::Imaging::PixelFormat::Format24bppRgb)
	{
		tmp = cvCreateImage(cvSize(bmp->Width, bmp->Height), IPL_DEPTH_8U, 3);
		tmp->imageData = (char*)bmData->Scan0.ToPointer();
	}
	else
	{
		tmp = cvCreateImage(cvSize(bmp->Width, bmp->Height), IPL_DEPTH_8U, 4);
		tmp->imageData = (char*)bmData->Scan0.ToPointer();

	}
	bmp->UnlockBits(bmData);
	cv::Mat cvImage = cv::cvarrToMat(tmp);
	cvReleaseImage(&tmp);
	return cvImage;
}

第二部分:mat转bitmap

这部分参考:https://gitee.com/jsxyhelu2020/gocw?_from=gitee_search

System::Drawing::Bitmap^ MatToBitmapC3(const cv::Mat& img)
{
	//create the bitmap and get the pointer to the data
	PixelFormat fmt(PixelFormat::Format24bppRgb);
	Bitmap^ bmpimg = gcnew Bitmap(img.cols, img.rows, fmt);
	BitmapData^ data = bmpimg->LockBits(System::Drawing::Rectangle(0, 0, img.cols, img.rows), ImageLockMode::WriteOnly, fmt);
	Byte* dstData = reinterpret_cast<Byte*>(data->Scan0.ToPointer());
	unsigned char* srcData = img.data;
	for (int row = 0; row < data->Height; ++row)
	{
		memcpy(reinterpret_cast<void*>(&dstData[row * data->Stride]), reinterpret_cast<void*>(&srcData[row * img.step]), img.cols * img.channels());
	}
	bmpimg->UnlockBits(data);
	return bmpimg;
}

第三部分:多曝光融合

c#对应Bitmap[]

System::Drawing::Bitmap^ CVDoNet::BitmapMergeMertens(cli::array<System::Drawing::Bitmap^>^ imgs, int len)
{
	vector<Mat> images;
	for (int i = 0; i < len; i++)
	{
		Mat mat = BitmapToMat(imgs[i]);
		images.push_back(mat);
	}

	Ptr<AlignMTB> alignMTB = createAlignMTB();
	alignMTB->process(images, images);

	Mat srcImg;
	Ptr<MergeMertens> mergeMertens = createMergeMertens();
	mergeMertens->process(images, srcImg);

	Mat dstImg;
	//**注意这部分代码,mergeMertens->process后,类型改为CV_32FC3**
	**srcImg.convertTo(dstImg, CV_8UC3, 255.0);**

	return MatToBitmapC3(dstImg);
}

第四部分:CLR项目主体

OpenCVDoNet.h文件

#pragma once

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <stdint.h>
#using <system.drawing.dll>
using namespace System;
using namespace System::Data;
using namespace System::IO;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace cv;
using namespace std;
namespace OpenCVDoNet
{
	public ref class CVDoNet
	{
	public:
		System::Drawing::Bitmap^ MergeMertens(cli::array<System::Drawing::Bitmap^>^ imgs, int len);
	};
}

OpenCVDoNet.cpp文件
#include "pch.h"
#include "OpenCVDoNet.h"
using namespace OpenCVDoNet;
//将1 2 3部分代码添加到下面
...

第五部分:C#部分

using OpenCVDoNet;
CVDoNet openCV = new CVDoNet();
Bitmap[] imgs = { (Bitmap)Image.FromFile("1.jpg"), (Bitmap)Image.FromFile("2.jpg"), (Bitmap)Image.FromFile("3.jpg") };
Bitmap bmp = openCV.MergeMertens(imgs, imgs.Length);
pictureBox1.BackgroundImage = bmp as Image;

srcImg.convertTo(dstImg, CV_8UC3, 255.0);
上面这段搞了1天,最后才知道融合过后的类型为CV_32FC3,转为CV_8UC3后,解决问题,至于能不能转16UC3或者其余的格式,理论上是可以的,但是需要跟PixelFormat对应上,也欢迎大家对转换这一块的留言建议,转CV_8UC3后的图像也有一定的效果,但是不理想

第六部分:相关简要配置

OpenCV4.8配置
项目属性页面–>配置属性–>VC++目录
C:\OpenCV480-CPU 输入自己的目录
包含目录:
C:\OpenCV480-CPU\include\opencv2
C:\OpenCV480-CPU\include
库目录:
C:\OpenCV480-CPU\x64\vc16\lib
链接器–>输入
附加依赖项:
opencv_world480.lib

CLR项目修改:
配置属性–>高级
公共语言运行时支持:公共语言运行时支持(/clr)
.Net目标框架版本:V4.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值