[笔记]C++ & C#影像处理-assert、二维影像与填充

前言

上一章介绍的色彩空间转换,都是使用一维阵列处理,接着因为要用到类似捲积的方式去做滤镜,所以将一维阵列转为二维阵列存取能增加可读性,而在转二维阵列之前要先实现填补功能,而在OpenCV函数为copyMakeBorder,它有很多不同的填补类型,今天我们要做的单纯补上0跟捲积处理方式一样,以下开始介绍填补。

Assert

这里使用到Assert是方便进行Debug(单元测试也很好用),主要将自己认为绝对不可能地排除在外,若不成立则会跳出错误讯息,详细使用可到assert观看,而[1]提到加入#define NDEBUG,assert就会关闭(assert也会吃效能,发行通常会关闭)。

填补

填补是将上下左右扩充到需要的大小,假如填补为1,如下图,可以看到要填补的地方为红色和蓝色,而在C++能使用拷贝记忆体值的函数memcpy来去达成,输出图的大小则是在C#函数处理好,为了记忆体方便自己控管尽量不要在C++回传指标。
输出图大小为:(输入图宽 + 2 * padding) * (输入图高 + 2 * padding)。
http://img2.58codes.com/2024/201105645CaINk7jhY.png

C++加入ImagePadding8bit函数:
标头档:Library.h

/*ImagePadding8bit Parameter:src= source of imagepur= purpose of imagewidth= Image's widthheight= Image's heightpad= padding size*/void ImagePadding8bit(C_UCHAE* src, UCHAE* pur, C_UINT32 width, C_UINT32 height, C_INT32 pad);

加入实作档:Library.cpp

srcEnd指向最后一个位置,然而複製的src给的都是最前面位置,所以这里设为src < srcEnd,若设等于则会超过原始大小(memcpy複製src到(src + copySize))pur直接跳到pad列pad行複製输入图。
void Library::ImagePadding8bit(C_UCHAE* src, UCHAE* pur, C_UINT32 width, C_UINT32 height, C_INT32 pad){assert(src != nullptr && pur != nullptr);assert(width > 0 && height > 0);assert(pad >= 0);C_UINT32 copySize = width * sizeof(UCHAE);C_UINT32 purWidth = (width + 2 * pad);C_UCHAE* srcEnd = src + width * height;pur += (pad * purWidth) + pad;while (src < srcEnd){memcpy(pur, src, copySize);pur += purWidth;src += width;}}

C#加入mndtImagePadding8bit函数:
MNDTLibrary.cs

        [DllImport(DLL_PATH)]        unsafe private static extern void mndtImagePadding8bit(IntPtr src, IntPtr pur, int width, int height, int pad);        public Bitmap ImagePadding8bit(Bitmap srcImage, int pad)        {            Bitmap purImage = new Bitmap(srcImage.Width + pad * 2, srcImage.Height + pad * 2, PixelFormat.Format8bppIndexed);            Rectangle size = new Rectangle(0, 0, srcImage.Width, srcImage.Height);            BitmapData srcData = srcImage.LockBits(size, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);            BitmapData purData = purImage.LockBits(size, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);            unsafe            {                IntPtr srcPtr = srcData.Scan0;                IntPtr purPtr = purData.Scan0;                mndtImagePadding8bit(srcPtr, purPtr, srcImage.Width, srcImage.Height, pad);            }            purImage.Palette = _colorPalette;            srcImage.UnlockBits(srcData);            purImage.UnlockBits(purData);            return purImage;        }

呼叫方式,先转为灰阶8bit。

Bitmap bitmap =  _lib.Change8BitColor(_fileImage, ColerType.BGR2GRAY_8BIT);pic_pur.Image = _lib.ImagePadding8bit(bitmap, 10);

http://img2.58codes.com/2024/20110564KkPIHYDggJ.png

二维影像

目前只有长、宽和二维指标。
主要建立height大小指标指向每个width的第一个,解构式记得要删除指标并指向nullptr。
新增标头档:Image.h

#pragma once#ifndef IMAGE_H#define IMAGE_H#include "general.h"class Image{public:/*Image Parameter:src= source of imagewidth= Image widthheight= Image heighttype= Image type*/Image(UCHAE* src, C_UINT32 width, C_UINT32 height, C_UINT32 type);~Image();UINT32 Width() const;UINT32 Height() const;UCHAE** image;private:MNDT::ImageType _type;UINT32 _width;UINT32 _height;};#endif // !IMAGE_H

新增实作档:Image.cpp

#include "Image.h"Image::Image(UCHAE* src, C_UINT32 width, C_UINT32 height, C_UINT32 type){_width = width;_height = height;_type = static_cast<MNDT::ImageType>(type);image = new UCHAE*[height];for (UINT32 index = 0; index < height; index++){*(image + index) = (src + width * index);}}Image::~Image(){delete[] image;image = nullptr;}UINT32 Image::Width() const {return _width;}UINT32 Image::Height() const {return _height;}

结语

接着就可以开始介绍各式各样的滤波器,后面使用滤波器的频率会很大所以必须先知道这些方便往后处理,若有问题欢迎提问和指导。

参考网址

[1]http://www.cplusplus.com/reference/cassert/assert/


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章