一:算法介绍

以前做过一个抠图的程序,是基于每个像素的4领域或者8领域,找出满足的所有点,从而填满了满足的区域。

基于8领域填充的地址为:http://nbcoders.com/detail/109. 这种方法很容易实现,但是缺点也很明显,就是效率不高。因为这种方法会将当前没有处理的所有的像素都放进队列之中,从而遍历队列时间和空间会大大增加

本文用的是一种线性区域填充的方法,是一种沿水平扫描线填充的方法。而不需要将每个未处理而又满足条件的像素都保存起来,而是只需要保留扫描线的最左端和最右端的像素点。从而避免了大量的无用遍历和节约了空间

二:算法描述

扫描线算法的基本填充方式是从种子点A出发,分别向左和向右扫描填充满足条件的像素点,分别将最左边和最右边的像素点的位置坐标记下,将其放入栈中。接着,再确定这条扫描线上下相邻的区域,按照同样的方法,并保存该保存的信息。如此重复,直到栈为空。

详细步骤如下:

1.将种子点A入栈

2.将种子点出栈,所在的行进行扫描线扫描满足的所有点,并记下最左边点left和最右边点Right和行号row,将其入栈。

3. 将栈中的点出栈,扫描该行中相邻上下两行,即row-1和row+1行,并记下最左边和最右边的点,入栈。

4.重复第3步,直到栈为空。

三:代码实现

//栈结构
struct Range
{int left;int right;int row;
};
//整个区域填充
void CMagicWand::regionFill(IplImage* src, IplImage* dst, int x, int y, int value)
{int width = src->width;int height = src->height;int matrixWidthstep = m_pIsVisitedMatrix->widthStep;int grayImgWidthstep = m_pGrayImg->widthStep;grayValue = (uchar)m_pGrayImg->imageData[y*grayImgWidthstep + x];//将第一个点标记并进行扫描线linearFill(x, y);while (m_vStackRange.size()>0){Range range = m_vStackRange.back();m_vStackRange.pop_back();int i = range.left;int j = range.right;int row = range.row;while (i<range.right){if(row+1 < height && range.row > 0 && range.row < height && (uchar)m_pIsVisitedMatrix->imageData[(row+1)*matrixWidthstep + i] <= 0 && abs((uchar)m_pGrayImg->imageData[(row+1)*grayImgWidthstep + i] - grayValue) < m_iThresholdValue ){linearFill(i, row+1);}if(row-1 >=0  && range.row > 0 && range.row < height && (uchar)m_pIsVisitedMatrix->imageData[(row-1)*matrixWidthstep + i] <= 0&& abs((uchar)m_pGrayImg->imageData[(row-1)*grayImgWidthstep + i] - grayValue) < m_iThresholdValue){linearFill(i, row-1);}++i;}}
}//实现一行扫描
void CMagicWand::linearFill(int x, int y)
{int width = m_pGrayImg->width;int matrixWidthstep = m_pIsVisitedMatrix->widthStep;int grayImgWidthstep = m_pGrayImg->widthStep;    // grayValue = (uchar)m_pGrayImg->imageData[y*grayImgWidthstep + x];int tempLeft = x;while (true){m_pIsVisitedMatrix->imageData[y*matrixWidthstep + tempLeft] = 1;setDstImg(tempLeft, y);if(--tempLeft<=0 || (uchar)m_pIsVisitedMatrix->imageData[y*matrixWidthstep + tempLeft] >0 || abs((uchar)m_pGrayImg->imageData[y*grayImgWidthstep + tempLeft] - grayValue) >= m_iThresholdValue){break;}uchar aaa =  (uchar)m_pIsVisitedMatrix->imageData[y*matrixWidthstep + tempLeft];}int tempRight = x;while (true){setDstImg(tempRight, y);m_pIsVisitedMatrix->imageData[y*matrixWidthstep + tempRight] = 1;if(++tempRight>=width || (uchar)m_pIsVisitedMatrix->imageData[y*matrixWidthstep + tempRight] >0 || abs((uchar)m_pGrayImg->imageData[y*grayImgWidthstep + tempRight] - grayValue) >= m_iThresholdValue){break;}}//这里防止扫描到图片外面去tempLeft = clampMin(tempLeft, 0);tempRight = clampMax(tempRight, width);Range range;range.left = tempLeft;range.right = tempRight;range.row = y;m_vStackRange.push_back(range);
}


四:效果展示

魔棒工具,线性区域填充算法实现相关推荐

  1. ML:基于自定义数据集利用Logistic、梯度下降算法GD、LoR逻辑回归、Perceptron感知器、SVM支持向量机、LDA线性判别分析算法进行二分类预测(决策边界可视化)

    ML:基于自定义数据集利用Logistic.梯度下降算法GD.LoR逻辑回归.Perceptron感知器.支持向量机(SVM_Linear.SVM_Rbf).LDA线性判别分析算法进行二分类预测(决策 ...

  2. ML之LoR:LoR之二分类之线性决策算法实现根据两课成绩分数~预测期末通过率(合格还是不合格)

    ML之LoR:LoR之二分类之线性决策算法实现根据两课成绩分数~预测期末通过率(合格还是不合格) 目录 输出结果 代码设计 输出结果 LoR之二分类算法实现预测期末考试成绩合格还是不合格 LoR回归函 ...

  3. 通俗解释优化的线性感知机算法:Pocket PLA

    个人网站:红色石头的机器学习之路 CSDN博客:红色石头的专栏 知乎:红色石头 微博:RedstoneWill的微博 GitHub:RedstoneWill的GitHub 微信公众号:AI有道(ID: ...

  4. C++Adaline自适应线性神经网络算法(附完整源码)

    C++Adaline自适应线性神经网络算法 C++Adaline自适应线性神经网络算法完整源码(定义,实现,main函数测试) C++Adaline自适应线性神经网络算法完整源码(定义,实现,main ...

  5. 多类线性分类器算法原理及代码实现 MATLAB

    多类线性分类器算法原理及代码实现 MATLAB 一.算法原理 下面举例说明为何蓝圈部分在case2中是确定的而在case1中不确定: 二.代码实现 1.HK函数 function [] = HK(w1 ...

  6. Fisher线性判别算法原理及实现 MATLAB

    Fisher线性判别算法原理及实现 MATLAB 一.Fisher判别器原理 二.代码实现 clc; close all; clear; %% 生成数据 rng(2020); %指定一个种子 mu1 ...

  7. Hessian局部线性嵌入算法(HLLE)——matlab实现

    好久没写了最近想把之前做过的一写算法发上来,发现只找到一字儿ppt,内容可能不详细忘大家谅解:不过我会把matlab的代码发上来,文章具体内容要是不理解大家可以上网找一些相关文章阅读: Hessian ...

  8. CG-光栅图形学区域填充算法-学习笔记

    一.区域填充 1. 与多边形扫描转换算法对比 1)基本思想不同 a. 多边形扫描转换是指将多边形的顶点表示转化为点阵表示: b. 区域填充只改变区域的填充颜色,不改变区域表示方法: 2)基本条件不同 ...

  9. 洪水填充算法_区域填充算法和多边形填充的扫描线算法

    本文主要介绍几种区域填充算法,重点解释多边形的扫描线填充算法,最后实现了多边形填充算法,包括在附录文件中.在参考[5]中,作者详细介绍了一系列区域填充算法,可以查看相应网页.代码的下载地址为:http ...

最新文章

  1. Udacity机器人软件工程师课程笔记(二十三) - 控制(其一)- PID控制及其python实现
  2. 比较MongoDB在公有云上的性能:AWS、Azure和Digital Ocean
  3. 如何使方法行数达到最优、常量与变量如何优雅的定义?
  4. 基于mini2440的看门狗(裸机)
  5. 初等数论--整除--线性组合与最大公因数之间的关系
  6. 与Netflix合作 美电视运营商推出4K频道
  7. IE下及标准浏览器下的图片旋转(二)—— Canvas(2)
  8. 那些把公司当家的程序员,后来怎么样了...
  9. 【转】UINavigationBar 使用总结
  10. Socket I/O模型全接触
  11. 接口测试——测试用例执行
  12. YII与Ace Admin 的集成
  13. python的DataFrame排序问题
  14. netdevice - 底层访问 Linux 网络设备
  15. 开源项目学习之(二)------iBase4J环境搭建
  16. 20190131-JS - Promise使用详解--摘抄笔记
  17. 有关MSSQL2000在Win7上的安装
  18. 电脑有时突然黑屏,过一两秒就好了的问题解决
  19. 2021消防设施操作员考试实操口述题及答案解析
  20. conda查看版本包命令

热门文章

  1. ios12电池测试软件,5款旧iPhone升级iOS12.3.1续航测试:真的有提升
  2. python嵌套列表怎么遍历_Python中遍历列表,循环嵌套
  3. html,css响应式布局案例练习--星巴克官网demo
  4. WPF 实现语言在线切换
  5. Java自动回复脚本
  6. 双目立体感知「走下神坛」?鼻祖斯巴鲁启用单目摄像头
  7. 搬砖的开始 HFSS入门 T型波导的内场分析
  8. Vue中TipTap富文本编辑器的输入框内部分样式无法显示
  9. Upyun 图片存储
  10. IEC61131与IEC61499 的集成与融合