当前位置: 首页 > wzjs >正文

武汉论坛有哪些南京seo优化

武汉论坛有哪些,南京seo优化,石首网站建设,手动清理wordpress缓存背景 在做一些线扫相机且进行连续拍摄的项目时,由于图像扫描的随机性,部分场景下需要对图像进行拼接和裁切,获取完整的一个图像。由于halcon中 crop相关的算子都是开辟新的内存方式,为了避免内存重复开辟,此处提供一个…

背景

在做一些线扫相机且进行连续拍摄的项目时,由于图像扫描的随机性,部分场景下需要对图像进行拼接和裁切,获取完整的一个图像。由于halcon中 crop相关的算子都是开辟新的内存方式,为了避免内存重复开辟,此处提供一个逻辑方式如下:

优点:

1)不需要每次都去新建内存,每次只需要做mem_copy的动作,减少耗时

2)在完整图像中查找特征,避免特征由于随机性拍照不完整而丢失

缺点:

1)如果直接复用指针,可能会导致拼接输出图像频率>检测频率,即缓存[0]的图片输出后,但检测未完成,此处队列循环又来到了缓存[0],最终导致原本的缓存[0]图像被覆盖,图像信息丢失。解决方式:可以修改为新建内存输出,会浪费一些cpu和内存

内存操作相关代码:

 public static class IntPtrHelper{/// <summary>/// 拷贝指针数据/// </summary>/// <param name="dest"></param>/// <param name="src"></param>/// <param name="count"></param>[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);/// <summary>/// 指针数据集重置/// </summary>/// <param name="dest"></param>/// <param name="c"></param>/// <param name="count"></param>/// <returns></returns>[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public static extern IntPtr MemSet(IntPtr dest, int c, int count);/// <summary>/// 从字节中拷贝数据至指针中/// </summary>/// <param name="destination"></param>/// <param name="sourcesBytes"></param>/// <param name="startIndex"></param>/// <param name="length"></param>public static void CopyFromBytes(this IntPtr destination, byte[] sourcesBytes,int startIndex,int length){Marshal.Copy(sourcesBytes, startIndex, destination, length);}/// <summary>/// 获取指针内指定位置的内容的字节/// </summary>/// <param name="sourcePtr"></param>/// <param name="sourceOffset"></param>/// <param name="length"></param>/// <returns></returns>public static byte[] ToBytes(this IntPtr sourcePtr,int sourceOffset,int length){byte[] rlt = new byte[length];Marshal.Copy(sourcePtr.Offset(sourceOffset), rlt, 0, length);return rlt;}/// <summary>/// 从一个指针的数据拷贝到另一个指针中/// </summary>/// <param name="source">数据源指针</param>/// <param name="destination">目标指针</param>/// <param name="sourceOffset">数据源指针偏移值</param>/// <param name="destinationOffset">目标指针偏移值</param>/// <param name="length">拷贝长度</param>public static void Copy(IntPtr source, IntPtr destination, int sourceOffset, int destinationOffset, int length){IntPtr destPtr = destination.Offset(destinationOffset),srcPtr = source.Offset(sourceOffset);CopyMemory(destPtr, srcPtr, (uint)length);}/// <summary>/// 指针偏移指定长度/// </summary>/// <param name="sourcePrt"></param>/// <param name="offset"></param>/// <returns></returns>public static IntPtr Offset(this IntPtr sourcePrt, int offset){IntPtr rltPtr;if (IntPtr.Size == sizeof(long)){rltPtr = new IntPtr(sourcePrt.ToInt64() + offset);}else{rltPtr = new IntPtr(sourcePrt.ToInt32() + offset);}return rltPtr;}/// <summary>/// 拷贝源指针指定位置的内容,返回新的指针.注意:此处的指针需要自己释放,不纳入内存管理/// </summary>/// <param name="source"></param>/// <param name="offset"></param>/// <param name="length"></param>/// <returns></returns>public static IntPtr Copy(IntPtr source, int offset, int length){IntPtr ptr = Marshal.AllocHGlobal(length);Copy(source, ptr, offset, 0, length);return ptr;}}

一、循环队列

设置根据图片 宽度/高度/通道数/缓存个数 创建一个循环队列,每次在完整一张图片拼接截取后,自动移到下一张图片,假设缓存个数为3,则就是 [0,1,2,0,1,2,0....]这样无限循环取图片缓存进行内存拷贝覆盖,代码如下

  /// <summary>/// 拷贝图像/// </summary>/// <param name="source">原始图像</param>/// <param name="destination">需拷贝到的图像位置</param>/// <param name="sourceOffset"></param>/// <param name="destinationOffset"></param>/// <param name="length"></param>/// <param name="imageType"></param>/// <param name="imageChannel"></param>public static void Copy(HImage source, HImage destination, int sourceOffset, int destinationOffset, int length,emImageType imageType, emVerticalImageChannel imageChannel){KeyValuePair<IntPtr, IntPtr>[] ptrParis = null;if(imageChannel == emVerticalImageChannel.one){//单通道IntPtr ptrSrc = source.GetImagePointer1(out string _, out int width, out int height);IntPtr ptrDestination = destination.GetImagePointer1(out string _, out width, out height);ptrParis = new KeyValuePair<IntPtr, IntPtr>[1] {new KeyValuePair<IntPtr, IntPtr>(ptrSrc,ptrDestination)};}else{//三通道source.GetImagePointer3(out IntPtr ptr1Src, out IntPtr ptr2Src, out IntPtr ptr3Src, out string _, out int width, out int height);destination.GetImagePointer3(out IntPtr ptr1Destination, out IntPtr ptr2Destination, out IntPtr ptr3Destination, out string _, out width, out height);ptrParis = new KeyValuePair<IntPtr, IntPtr>[3] {new KeyValuePair<IntPtr, IntPtr>(ptr1Src,ptr1Destination),new KeyValuePair<IntPtr, IntPtr>(ptr2Src,ptr2Destination),new KeyValuePair<IntPtr, IntPtr>(ptr3Src,ptr3Destination),};}int pixelByteNumber = imageType.GetPixelByteNumber(); //获取图片类型一个像素对应的字节数foreach(KeyValuePair<IntPtr,IntPtr> kvp in ptrParis){//循环拷贝IntPtrHelper.Copy(kvp.Key, kvp.Value, sourceOffset* pixelByteNumber, destinationOffset* pixelByteNumber, length* pixelByteNumber);}}

二、查找特征确定行起始和行终点

此处需要自己实现算法,最终目的就是找到你要的图片的起始行坐标和终止行坐标

三、输出图像

有了起始行坐标和终止行坐标后,我们只需要拿出对应的内存指针,调用GenImage1Extern或GenImage3Extern进行图片生成即可。需要注意的是要用HImage2来使用图像,因为假设原始那张缓存图片被释放掉,那么就会出现访问野指针的情况,毁灭性打击。

        public class HImage2:HImage{/// <summary>/// 引用的图像/// </summary>public HImage ReferenceData { get; set; }public HImage2(HImage referenceImage, HObject hObject):base(hObject){//智能指针,不需要拷贝内存新建的问题,此处避免由于缓存中图像释放导致此处访问野指针的问题ReferenceData = new HImage(referenceImage);}public override void Dispose(){base.Dispose();ReferenceData?.Dispose();ReferenceData = null;}}/// <summary>/// 根据垂直方向的位置的长度,进行图像裁切,且图像引用原来的指针/// </summary>/// <param name="image"></param>/// <param name="top">起始行坐标</param>/// <param name="height">高度</param>/// <returns></returns>public static HImage2 CropVerticalReference(this HImage image,int top,int height){int channel = image.CountChannels().I;image.GetImageSize(out int widthSrc, out int heightSrc);if(top+height>heightSrc){throw new Exception($"裁切终止行为{top + height},超出图像高度{heightSrc}");}if(channel == 1){IntPtr ptr = image.GetImagePointer1(out string type, out  widthSrc, out  heightSrc);emImageType typeEm = (emImageType)Enum.Parse(typeof(emImageType), type, true);int scale = typeEm.GetPixelByteNumber();IntPtr offsetPtr = ptr.Offset(scale * top * widthSrc);HOperatorSet.GenImage1Extern(out HObject temp, type, widthSrc, height, offsetPtr, 0);HImage2 rlt = new HImage2(image, temp);temp.Dispose();return rlt;}else if(channel == 3){image.GetImagePointer3(out IntPtr pRed, out IntPtr pGreen, out IntPtr pBlue, out string type, out widthSrc, out heightSrc);emImageType typeEm = (emImageType)Enum.Parse(typeof(emImageType), type, true);int scale = typeEm.GetPixelByteNumber();IntPtr offsetPtrRed = pRed.Offset(scale * top * widthSrc);IntPtr offsetPtrGreen = pGreen.Offset(scale * top * widthSrc);IntPtr offsetPtrBlue = pBlue.Offset(scale * top * widthSrc);HOperatorSet.GenImage3Extern(out HObject temp, type, widthSrc, height, offsetPtrRed, offsetPtrGreen, offsetPtrBlue, 0);HImage2 rlt = new HImage2(image, temp);temp.Dispose();return rlt;}else{throw new Exception($"不支持通道数为{channel}的图像裁剪.");}}

总结

该方式适用于大图像的垂直方向拼接并截取检测,减少内存消化,同时避免野指针的问题。

http://www.dtcms.com/wzjs/55451.html

相关文章:

  • 成都农产品网站建设方案新闻式软文
  • 网站建设如何提高浏览量百度指数移动版
  • 阿里云 wordpress 区别百度网站排名优化价格
  • 太原网站建设质量推荐零售客户电商网站
  • 自学网网站外包公司怎么赚钱
  • 那个网站做旅游规划好app拉新怎么做
  • 怎样自己做电影网站色盲色弱测试
  • 宁乡网站开发公司推荐google优化排名
  • 日本可以自己做网站吗?好搜搜索
  • 无为县建设局网站模板建站流程
  • 怎么建设属于自己的网站中国新闻
  • 定制版网站建设费用360网站seo手机优化软件
  • 平面设计平台有哪些seo实战密码电子版
  • 长沙做旅游网站多少钱深圳优化公司义高粱seo
  • 网站建设日程表个人如何在百度上做广告
  • 下列哪些属于营销型网站的基础建设如何推广普通话
  • asp.net+制作网站开发深圳博惠seo
  • 一级a做爰片软件网站山西太原网络推广
  • 日喀则市住房和城乡建设局网站crm客户管理系统
  • 莱芜建设网站2023网络营销成功案例
  • 好的企业网站建设上海整站seo
  • wordpress安装中文seo软件哪个好
  • 施工企业工作环境关键词自动优化
  • 做网站基本教程百度seo软件优化
  • 番禺网站建设公司百度推广怎么做步骤
  • 算命网站建设开发深圳推广平台深圳网络推广
  • 泰安网站制作湖南关键词网络科技有限公司
  • 找个人合伙做网站高清网站推广免费下载
  • 网站域名查询网址关键词排名关键词快速排名
  • 彩票网站怎么做推广北京网站seo费用