图像之魔棒工具实现

您所在的位置:网站首页 an魔术棒工具 图像之魔棒工具实现

图像之魔棒工具实现

2024-07-08 08:45| 来源: 网络整理| 查看: 265

http://blog.csdn.net/ixshells/article/details/41278955

  这是以前发的一篇文章,虽然自己已经在csdn上发布了第二篇类似文章,现在还是都发上来。

   原文地址:http://nbcoders.com/tu-xiang-zhi-mo-bang-gong-ju.html

魔棒工具对于做过ps的同学应该都不陌生,本文就介绍下魔棒工具在图像中的实现原理以及实现。

 

1.魔棒工具

还是用一组图来介绍下魔棒工具的使用

如上图所示,魔棒工具就是能够快速选中并抠去选中区域的小工具。

2.解决思路

因为才不久做了一个程序效果很类似,使用的阀值分割和边缘检测来做。所以,当看到要实现这个效果的时候我的第一反应便是朝着这个

方向去了。通过阀值分割将图片的颜色区域进行分类,再在这个类别中选中其中的特定类别。或者是通过边缘检测方式检测出边缘后,再得出边缘中所围住选中的那个像素点的区域。刚开始想的思路大致是这样。

当看到PS的魔棒工具中的参数后,思路基本就确定了。思路并不是通过阀值分割和边缘检测,而是通过计算周围与该像素点的相似像素的一个区域。即点中一个像素点,该像素点向周围扩张,找取与该像素点相似的像素点的一个区域。ps中参数如下图:

               

ps中对自动选中某个区域效果最主要的是前面两个参数:取样大小和容差。其中取样大小是进行计算时,不是只是单个计算,是计算这个像素周围领域的平均值来比较像素值的相似度。

3.实现步骤

1.如何找出相似点

方式是通过将图转化成灰图,灰度图是像素从由浅到深进行分类。如果灰度像素差值在一定范围类,那么将两像素视为相似。

2.如何找出选中区域

通过鼠标点中图的点向周期扩张成一个相似区域。将与该像素值相似的点放入相似队列 中,再找出相邻8领域中的点。直到找出所有的点。大致方式如下图所所示

    

4. 关键函数实现

这里的实现方式是通过OpenCV实现,但也只是用了OpenCV基本的数据结构和函数

 

[cpp] view plain copy   //相似像素队列结构   struct Queue    {       int x;       int y;       Queue* next;   };      void getMagicWandRegion(const IplImage* src, IplImage* dst, int seedx, int seedy, int threshold)   {       //如果传入图不是灰度图则返回       if(!src || src->nChannels != 1)return ;          int width = src->width;       int height = src->height;       int srcWidthStep = src->widthStep;       uchar* img = (uchar*)src->imageData;          //标记每个像素点是否被计算过,这里用一单通道图来标记       IplImage* M = cvCreateImage(cvSize(width, height), 8, 1);       int Mwidthstep = M->widthStep;       cvZero(M);       M->imageData[seedy * Mwidthstep + seedx] = 1;    //种子点位置为1,其它位置为0          //队列的两端       int start = 0;       int end = 1;              //将第一个像素点入队列       Queue *queue = new Queue;       queue->x = seedx;       queue->y = seedy;       queue->next = NULL;       Queue *first = queue;       Queue *last = queue;          //第一个像素点的值       uchar pixel = (uchar)img[seedy * srcWidthStep + seedx];          while (end - start > 0)       {           int x = first->x;           int y = first->y;              //向周围扩展搜索           for (int yy = -1; yyy = cy;                           node->next = NULL;                              end++;                           last->next = node;                           last = node;                              M->imageData[cy * Mwidthstep + cx] = 1;                       }                   }               }           }           Queue* temp = first;           first = first->next;           delete temp;           start++;       }          //此处将图扩展区域内变为黄色,不是关键代码,代码省去             cvReleaseImage(&M);   }  

 

5. 效果展示

    这里直接将素相似区域(魔棒相似区域设置为黄色)

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3