zoukankan      html  css  js  c++  java
  • 图像之魔棒工具实现

    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
     
    1. //相似像素队列结构  
    2. struct Queue   
    3. {  
    4.     int x;  
    5.     int y;  
    6.     Queue* next;  
    7. };  
    8.   
    9. void getMagicWandRegion(const IplImage* src, IplImage* dst, int seedx, int seedy, int threshold)  
    10. {  
    11.     //如果传入图不是灰度图则返回  
    12.     if(!src || src->nChannels != 1)return ;  
    13.   
    14.     int width = src->width;  
    15.     int height = src->height;  
    16.     int srcWidthStep = src->widthStep;  
    17.     uchar* img = (uchar*)src->imageData;  
    18.   
    19.     //标记每个像素点是否被计算过,这里用一单通道图来标记  
    20.     IplImage* M = cvCreateImage(cvSize(width, height), 8, 1);  
    21.     int Mwidthstep = M->widthStep;  
    22.     cvZero(M);  
    23.     M->imageData[seedy * Mwidthstep + seedx] = 1;    //种子点位置为1,其它位置为0  
    24.   
    25.     //队列的两端  
    26.     int start = 0;  
    27.     int end = 1;  
    28.       
    29.     //将第一个像素点入队列  
    30.     Queue *queue = new Queue;  
    31.     queue->x = seedx;  
    32.     queue->y = seedy;  
    33.     queue->next = NULL;  
    34.     Queue *first = queue;  
    35.     Queue *last = queue;  
    36.   
    37.     //第一个像素点的值  
    38.     uchar pixel = (uchar)img[seedy * srcWidthStep + seedx];  
    39.   
    40.     while (end - start > 0)  
    41.     {  
    42.         int x = first->x;  
    43.         int y = first->y;  
    44.   
    45.         //向周围扩展搜索  
    46.         for (int yy = -1; yy<=1; yy++)  
    47.         {  
    48.             for (int xx = -1; xx<=1; xx++)  
    49.             {  
    50.                 int cx = x + xx;  
    51.                 int cy = y + yy;  
    52.                 if (cx >= 0 && cx <width && cy >=0 && cy < height)  
    53.                 {  
    54.                     //如果为相似点,那么将其入队,并标记  
    55.                     if (abs(img[cy * srcWidthStep + cx] - pixel) <= threshold && M->imageData[cy * Mwidthstep + cx] != 1)  
    56.                     {  
    57.                         Queue *node = new Queue;  
    58.                         node->x = cx;  
    59.                         node->y = cy;  
    60.                         node->next = NULL;  
    61.   
    62.                         end++;  
    63.                         last->next = node;  
    64.                         last = node;  
    65.   
    66.                         M->imageData[cy * Mwidthstep + cx] = 1;  
    67.                     }  
    68.                 }  
    69.             }  
    70.         }  
    71.         Queue* temp = first;  
    72.         first = first->next;  
    73.         delete temp;  
    74.         start++;  
    75.     }  
    76.   
    77.     //此处将图扩展区域内变为黄色,不是关键代码,代码省去  
    78.   
    79.   
    80.     cvReleaseImage(&M);  
    81. }  

    5. 效果展示

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

     

  • 相关阅读:
    转载: HashMap的工作原理
    什么web服务器、什么是应用服务器,常见的web服务器和应用服务器有哪些
    论文查重应对策略
    web测试方法总结
    软件测试中十大负面测试用例
    mysql 学习笔记
    Tomcat转jboss踩的那些坑
    实现简单的List功能
    java ScriptEngine 使用 (java运行脚本文件)
    rmi 工作原理
  • 原文地址:https://www.cnblogs.com/jukan/p/7825117.html
Copyright © 2011-2022 走看看