提取单图元轮廓

一. 应用场景!

使用过Genesis的朋友都知道,它可以提取你点击单图元中心<提取图元轮廓计算中心点>!


二.

由于工作需要,去年在师傅的知道下写了一个单图元轮廓提取算法!


三. 原理

提取轮廓即需要找出单图元最外(内)层连续不间断的点!

故我们需要一个起始点,即从你点击的单图元出发,向左(←↑→↓, 4个方向皆可,只需改变算子的起始点)遍历至第一个与点击点不用色调的点,此点极为最外层轮廓的起始点,然后以你所选方向为算子起始项,进行顺时针(逆时针)遍历,直到遍历点与起始点重合,说明轮廓提取完毕!


四.

本例中我采用向左顺时针遍历,剩余的7种就交给聪明的你了!


1)准备算子结构

123
0*4
765


typedef struct DOTS_ARR // 采用屏幕坐标,Y轴向下!
{
INT32 OffsetX; // 相对中心点X向的偏移量
INT32 OffsetY; // 相对中心点Y向的偏移量
INT32 NextDotIndex; // 此点为目标点,下次遍历位置索引
}DOTS_ARR;

2)未优化算子

DOTS_ARR DotsArr[] = 
{
-1,  0, 5,
-1, -1, 6,
0, -1, 7, // 上图中当前计算点的正上方2号点,若此点为最新提取的轮廓点,则下一点应为此点相对位置7开始遍历,原因如下:
1, -1, 0,
1,  0, 1,
1,  1, 2,
0,  1, 3,
-1,  1, 4,
};

为了保证不遗漏,我们必须采取顺时针(逆时针)遍历当前点周围所有点(以上次遍历成功2号点为例)

123
0(1)*(2)4(3)
7(0)6(*)5(4)

()括号中为以上以中心点为相对位置的坐标

看到上图,聪明的朋友一定会说7不是最好的位置,1才是,应为0,7在上次的遍历中已经被排除了(you are right)!


故最优算子如下

DOTS_ARR DotsArr[] = 
{

-1,  0, 5,
-1, -1, 7,
0, -1, 1,
1, -1, 1,
1,  0, 3,
1,  1, 3,
0,  1, 5,
-1,  1, 5,
};


五. Demo
关键的算子已经序数完了,那么我用一个简单的Demo来实践一下!

1)先上一个提取后的效果图

2)简单的列几处关键代码:

1.创建一个简单窗口类单独用来绘制

 m_MyView.CreateEx(NULL, AfxRegisterWndClass(CS_HREDRAW,NULL,(HBRUSH)::GetStockObject(WHITE_BRUSH),NULL), L"CPaintView Window", WS_CHILD, m_MyViewRect, this, 0);
i
f (NULL == m_MyView)
{
TRACE(_T("Error:(%s.%d) CreateEx Failed!\r\n"), __FUNCTION__, __LINE__);
}
 


2.在窗口显示之前,加载我们的位图

if (bShow)// Show

{

m_hMemDC = CreateCompatibleDC(NULL);

HBITMAP hBitmap = LoadBitmapW(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_START));

BITMAP bmp;

GetObject(hBitmap, sizeof(BITMAP), &bmp);

m_BitmapSize.cx = bmp.bmWidth;

m_BitmapSize.cy = bmp.bmHeight;

m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, hBitmap);

}

else// Close

{

HBITMAP hBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hOldBitmap);

DeleteObject(m_hOldBitmap);

DeleteDC(m_hMemDC);

}

注意:一定要删除GDI对象,做到万浪丛中过,滴水不沾身,否则会造成GDI泄漏(进程中GDI对象达到9999个,此进程会奔溃)


3.在图元上打击做按钮时,提取轮廓!

#pragma region Get Contour Centerm_VectorContourPoint.clear();CDC *lpCDC = GetDC();HDC hClientDC = lpCDC->GetSafeHdc();RECT ContourRect = {};POINT ptStart = {};POINT ptErgod = {point.x, point.y};COLORREF iColorValue = GetPixel(hClientDC, point.x, point.y);while (iColorValue == GetPixel(hClientDC, ptErgod.x , ptErgod.y)){ptErgod.x--;}if (-1 == ptErgod.x){return;}ptErgod.x++;memcpy(&ptStart, &ptErgod, sizeof(POINT));ContourRect.left = ptStart.x;ContourRect.right = ptStart.x;ContourRect.top = ptStart.y;ContourRect.bottom = ptStart.y;INT32 Count = 0;INT32 FlagIndex = 0;do {for (INT32 i = 0; i < DotsArrCount; i++){if (iColorValue == GetPixel(hClientDC, ptErgod.x + DotsArr[FlagIndex].OffsetX, ptErgod.y + DotsArr[FlagIndex].OffsetY)){Count++;ptErgod.x += DotsArr[FlagIndex].OffsetX;ptErgod.y += DotsArr[FlagIndex].OffsetY;FlagIndex = DotsArr[FlagIndex].NextDotIndex;m_VectorContourPoint.push_back(ptErgod);break;}FlagIndex++;if (FlagIndex == DotsArrCount){FlagIndex = 0;}}ContourRect.left   = (ptErgod.x < ContourRect.left)   ? ptErgod.x : ContourRect.left;ContourRect.right  = (ptErgod.x > ContourRect.right)  ? ptErgod.x : ContourRect.right;ContourRect.top    = (ptErgod.y < ContourRect.top)    ? ptErgod.y : ContourRect.top;ContourRect.bottom = (ptErgod.y > ContourRect.bottom) ? ptErgod.y : ContourRect.bottom;} while (ptStart.x != ptErgod.x || ptStart.y != ptErgod.y);TRACE("Count is %d\r\n", Count);m_ptCenter.x = (ContourRect.left + ContourRect.right) >> 1;m_ptCenter.y = (ContourRect.top + ContourRect.bottom) >> 1;ReleaseDC(lpCDC);Invalidate(TRUE);
#pragma endregion

4)简单动态显示我们提取成果

	BitBlt(dc.GetSafeHdc(), 0, 0, m_BitmapSize.cx, m_BitmapSize.cy, m_hMemDC, 0, 0, SRCCOPY);for (vector<POINT>::iterator itPoint = m_VectorContourPoint.begin(); itPoint != m_VectorContourPoint.end(); itPoint++){if (itPoint == m_VectorContourPoint.begin()){MoveToEx(dc.GetSafeHdc(), (*itPoint).x + m_BitmapSize.cx, (*itPoint).y, NULL);}else{Sleep(1);LineTo(dc.GetSafeHdc(), itPoint->x + m_BitmapSize.cx, itPoint->y);}}

5)完成,运行过程中截图,运行完成即为之前贴出的预览图!

六.总结

师傅告诉我:图像算法的处理要长期的积累,自己去悟,多思考,当遇到一个新的算法需求,结合自己的经验积累,就能快速得到处理方法!

有兴趣的朋友可以不使用Demo中Getpixel(),而是直接处理位图数据块,这样轮廓提取的效率会更高!


这也是我去年学到第一个算法处理的,在这一年中,自己也积累了一些简单的图像处理算法:如灰度淡化(抽点),多图元骨架提取等!


最后希望图像处理大神不啬指出demo中的不足以及需要优化之处,谢谢!


七)Demo源码下载地址

http://download.csdn.net/detail/u012158162/9590647




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决: Failed to execute ... maven-deploy-plugin... Return code is: 401, ReasonPhrase: Unauthorized.

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 执行 mvn clean deploy , 想把本地代码 打包并推送到私服 &#xff0c;报错&#xff1a; [ERROR] Failed to execute goal org.a…

高速行车12条技巧,每一条都关乎你的生命

高速行车12条技巧&#xff0c;每一条都关乎你宝贵的生命。 1、长途旅行前&#xff0c;全面检查整车&#xff0c;防止漏油&#xff0c;轮胎检查是重点&#xff01; 在中国很多高速事故是可以避免的&#xff0c;绝大部分司机缺少本应该在驾校学到的必备知识&#xff0c;这导致很多…

文件逆序输出及根据行号索取该行内容

一. 起因 年初&#xff0c;一位同学提取了如何实现倒叙输出文件&#xff0c;根据行号索引该行内容&#xff0c;我思考了一下&#xff0c;得出以下二种方案&#xff01; 二. 方案 1&#xff09;方案1&#xff1a;&#xff08;此方案局限性较大&#xff0c;并且耗内存&#xff…

pom.xml 配置之:snapshot 快照库和 release发布库 的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、如果在发布时使用 mvn deploy -P release 的命令&#xff0c;那么会自动使用0.1作为发布版本&#xff0c;那么根据 maven 处理 snaps…

米饭凉一凉再吃会更加地健康

米饭&#xff0c;是人们日常饮食中的主角之一;一味米饭&#xff0c;与五味调配&#xff0c;几乎可以供给全身所需营养。大米性平、味甘;有补中益气、健脾养胃、益精强志、和五脏、通血脉、聪耳明目、止烦、止渴、止泻的功效。 人们往往认为米饭应该趁热的时候吃。 但是用电饭煲…

内存映射处理大文件并实现逆序输出

上一篇介绍了一种常见的文件处理方法(可优化为&#xff1a;分次读取文件&#xff0c;但要满足根据行号能快速索引该行内容时会遇到麻烦),所以此片我将介绍另一种更高效&#xff0c;实用&#xff0c;并对本进程的内存空间地址消耗小的方法&#xff01; 一. 预备知识 1&#xff…

解决: tar: Removing leading `/‘ from member names

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 。 使用绝对路径 执行 tar 命令&#xff1a; tar -zcvf clientOne.tar /root/jiangyu/projects/springCloud/clientOne/s…

ObjectArx创建指定块

ObjectArx创建自定义块 一. 目的仿照AutoCad的Block命令&#xff0c;实现简版创建块功能!二. 开发环境Win7操作系统&#xff0c;AutoCad2012&#xff0c; VS2008, ObjectArx_SDK_2012三. 相关函数简介1) int acedSSGet (const ACHAR *str, const void *pt1,const void *pt2…

告诉你中国著名的40个四大是什么?

中国著名的40个四大 一、四大江南才子&#xff1a;唐伯虎、文征明、祝枝山、徐祯卿&#xff1b; 二、四大才女&#xff1a;蔡文姬、班昭&#xff08;又说上官婉儿&#xff09;、卓文君、李清照&#xff1b; 三、四大名著&#xff1a;《三国演义》、《西游记》、《水浒传》、《…

解决:Dockerfile 中执行 tar 命令始终报错:tar: /xx/xx: Cannot stat: No such file or directory tar: Exiting with

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. docker 执行 build &#xff0c; dockerfile 中有一行命令&#xff1a; RUN tar -zcvP -f clientOne.tar /root/jiangyu/projects/…

ObjectArx创建自定义实体

ObjectArx创建自定义实体 一。目的在ObjectArx中已经有了许多实体&#xff0c;如AcDbLine,AcDbCircle,AcDbArc等&#xff0c;但在用户使用Cad时&#xff0c;会有一些对他们来讲常用的“实体“&#xff0c;如一扇门&#xff0c;如果我们能提供一个“门实体“&#xff0c;让用户能…

开车人千金难买的知识!(组图)

开车的人千金难买的知识: 前言&#xff1a; 一、 发动机是怎样被您自己开坏的 二、 变速箱是怎样被您自己开坏的 三、 排水口&#xff08;很重要您肯定不知道的&#xff09; 四、 离合 五、 水箱 六、 方向助力 七、 空调 八、底盘 九、爱车是如何被自己撞坏的&#x…

如何在 IDEA 启动多个 Spring Boot 工程实例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一个工程启动多个实例&#xff0c;分别占用不同的端口。 step 1 在IDEA上点击Application右边的下三角 ,弹出选项后&#xff0c;点击Ed…

安装micro/go-micro

创建文件夹&#xff0c;拉取相关包 mkdir golang.org cd golang.org mkdir x cd x git clone https://github.com/golang/net.git git clone https://github.com/golang/crypto.git git clone https://github.com/golang/sys.git git clone https://github.com/golang/…

刹车八个技巧 教你踩得又稳又好

驾车加速行驶&#xff0c;这是谁都可以做到的。但是如果我们不能够正确地操作刹车&#xff0c;汽车有可能在一瞬间变成事故的凶器&#xff0c;因此&#xff0c;也许我们可以说刹车技术是驾驶汽车的境界之一。以下为大家列举八种刹车技巧&#xff0c;如果全部掌握的话&#xff0…

springcloud 注解 @EnableDiscoveryClient 与 @EnableEurekaClient 的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在使用 Spring Cloud feign 服务发现时提到两种注解&#xff1a; EnableDiscoveryClient、EnableEurekaClient 。 spring cloud 中 disc…

开车路上怎样赶走瞌睡虫?网友支招如何防路困

春困秋乏&#xff0c;秋天时不时来个哈欠打个盹也是人之常情&#xff0c;可是如果您正在路上开车可就是危险之极的事情了&#xff01;要知道&#xff0c;这在路上开快车不是最危险的&#xff0c;最危险的是走神&#xff0c;而打瞌睡更是要命的&#xff01;可这打瞌睡是身体疲乏…

重启 docker 服务、Docker 重启

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我的情况 &#xff1a;重启阿里云 ECS 服务器后&#xff0c;一切服务都停止了。 重启 XXX 服务通用命令&#xff1a;service xxx re…

25岁肥胖!美研究:晚年恐出现病态肥胖

如果您现在刚好25岁&#xff0c;最好注意一下现在的体重&#xff0c;因为美国纽约大学最新研究发现&#xff0c;如果在25岁这个年龄&#xff0c;您的体重是超重的&#xff0c;10年后肥胖的机率会比较高&#xff0c;男生恐怕高到23.1%&#xff0c;女生高到46.9%&#xff0c;而年…

linux 查看 CPU 使用率

1&#xff1a;top 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 top -bn 1 -i -c top命令可以看到总体的系统运行状态和cpu使用效率 %us: 表示用户空间程序的cpu使用效率 %sy:表示…