洪水填充算法 - 忽略边缘

2023-12-31

到目前为止,我已经实现了洪水填充算法。我想调整它,这样它就可以去掉边缘。为了演示这一点,我上传了一张图片:

图1是我要修改的图像。图 3 是我的算法应该做的事情。图2是我当前的结果。

所以在这种情况下,targetColor 是白色,replacementColor 是绿色;

这是我到目前为止所做的伪代码。

doFloodFill(x,y,targetColor,replacementcolor) {

    if (x and y not in bounds of image) {
       return
    }

    if (color(x,y) IS NOT targetColor) {
       return
    }

    if (color(x+1, y) IS NOT targetColorOfFloodFill AND color(x+1, y) IS NOT replacementColor OR
        color(x-1, y) IS NOT targetColorOfFloodFill AND color(x-1, y) IS NOT replacementColor OR
        color(x, y+1) IS NOT targetColorOfFloodFill AND color(x, y+1) IS NOT replacementColor OR
        color(y, y-1) IS NOT targetColorOfFloodFill AND color(x, y-1) IS NOT replacementColor) {
        return;
    }

    image.setColor(x, y, replacementColor)

    doFloodFill(x+3,y,targetcolor,replacementcolor)
    doFloodFill(x-3,y,targetcolor,replacementcolor)
    doFloodFill(x,y+3,targetcolor,replacementcolor)
    doFloodFill(x,y-3,targetcolor,replacementcolor)
}

此调整已实施到我的洪水填充中。忽略它会导致洪水填充算法正常工作而不会出现任何问题。实际的问题是:如何区分边缘像素和区域内具有不同颜色的像素?

P.S: 我们可以假设 x, y 从区域内开始


我也会选择洪水填充补充。

不过,还有一个想法:

  • 像往常一样洪水泛滥
  • 跟踪边界的一个像素:例如最顶部的像素
  • 然后像老鼠一样沿着边界寻找逃脱,并再次使其变白。
const canvas = document.querySelector('canvas');

const M = `
00000000000000000000
00000110011111110000
00001111111110000000
00011111111111100000
00111111111101110010
01111111101111110010
01111111111111110110
01111111111111111110
01111111111111111100
01111111111111111100
01111111111111111100
01111111111111111000
00111111111111111000
00111111111111110000
00011111111111100000
00000000000000000000
`.trim().split('\n').map(x=>x.trim().split('').map(x=>parseInt(x)))

const mat = ({ x, y }, v) => {
  if (v) {
    M[y][x] = v
  }
  return M[y][x]
}
const left = ({x,y}) => ({ x: y, y: -x })
const right = ({x,y}) => ({ x: -y, y: x })
const back = ({x, y}) => ({ x: -x, y: -y})
const front = (pos, { x, y }) => ({ x: pos.x + x, y: pos.y + y })
const splinter = { 
  pos: {
    x: 5, 
    y: 1
  },
  orig: {
    x: 5,
    y: 1
  },
  dir: { x: 1, y: 0 },
  atStart() {
    return this.pos.x === this.orig.x && this.pos.y === this.orig.y
  },
  move () {
    if (this.atStart() && mat(this.pos) === 2) { return false }
    // wall on left
    if (mat(front(this.pos, left(this.dir))) === 0) {
      // wall on front
      if (mat(front(this.pos, this.dir)) === 0) {
        // wall on right
        if (mat(front(this.pos, right(this.dir))) === 0) {
          this.dir = back(this.dir)
        } else {
          this.dir = right(this.dir)
        }
      }
      this.poop()
    } else {
      this.dir = left(this.dir)
    }
    this.moveForward()
    return true
  },
  moveForward () {
    this.pos.x += this.dir.x
    this.pos.y += this.dir.y
  },
  poop () {
    mat({ x: this.pos.x, y: this.pos.y }, 2)
  },
  sprite () {
    if (this.atStart()) { return 'X' }
    if (this.dir.x === -1 && this.dir.y === 0) { return '←' }
    if (this.dir.x === 1 && this.dir.y === 0) { return '→'}
    if (this.dir.x === 0 && this.dir.y === 1) { return '↓' }
    if (this.dir.x === 0 && this.dir.y === -1) { return '↑' }
  }
}

function redraw () {
  const ctx = canvas.getContext('2d')
  const dw = canvas.width / M[0].length
  const dh = canvas.height / M.length
  const fill = ({ x, y }, color) => {
    ctx.fillStyle = color
    ctx.fillRect(x * dw, y * dh, dw, dh)
  }
  const colors = {
    1: 'green',
    0: 'black',
    2: 'white'
  }
  M.forEach((row, i) => {
    row.forEach((el, j) => {
      fill({ x: j, y: i }, colors[el])
    })
  })
  const char = splinter.sprite()
  ctx.strokeText(char, (splinter.pos.x + 0.1) * dw, (splinter.pos.y + 0.8) * dh)
}
redraw()
document.querySelector('button').onclick = _ => {
  splinter.move(); redraw()
}
document.querySelector('button.allmoves').onclick = _ => {
  while(splinter.move()){}
  redraw()
}
canvas{background:#eeeeee;}
<canvas width="160" height="160"></canvas>
<button>move, rat</button>
<button class="allmoves">move for your life, rat</button>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

洪水填充算法 - 忽略边缘 的相关文章

  • 计算排列中“反转”的数量

    设 A 为一个大小的数组N 我们称之为几个索引 i j 一个 逆 如果i lt j and A i gt A j 我需要找到一种接收大小数组的算法N 具有唯一的数字 并返回时间的倒数数O n log n 您可以使用归并排序 http en
  • 使用 Python 图像库 (PIL) 绘制抗锯齿线

    我正在使用 Python 图像库的 ImageDraw line 绘制一堆线条 但它们看起来很可怕 因为我找不到消除锯齿的方法 如何在 PIL 中消除锯齿线 这是一个非常快速地组合在一起的函数 用于用 PIL 绘制一条抗锯齿线 这是我在谷歌
  • 最快的 Sobel 边缘检测 C#

    我想制作一个实现索贝尔边缘检测的程序 这是我的代码 private Bitmap SobelEdgeDetect Bitmap ori Bitmap b original Bitmap bb original int width b Wid
  • 合并两个 ColorMatrix 或在 Imageview 上同时应用两个或多个 ColorMatrix

    我正在更改 ImageView 的亮度 对比度 饱和度和色调 我对此进行了很多搜索 我得到了一些可以使用的代码颜色矩阵 1 For 亮度ColorMatrix 是类似的东西 float brightness 50F 1 5F ColorMa
  • C# - 将 WPF Image.source 转换为 System.Drawing.Bitmap

    我发现很多人都在转换BitmapSource to a Bitmap 但是关于ImageSource to Bitmap 我正在制作一个成像程序 我需要从显示的图像中提取位图Image元素 有谁知道如何做到这一点 EDIT 1 这是一个用于
  • 递归分层父子

    我有一个来自数据库的项目集合 该数据库具有parentid值或空 这是我的班级设计 public class Item public int id get set public string Name get set public int
  • 如何在可可中获取图像的作者

    我不明白为什么metaDic 总是为空 有一个代码 CFDataRef dataRef CGDataProviderCopyData CGImageGetDataProvider img CGImage UIImage img CGImag
  • 准备与大数据相关的设计和架构问题的最佳方法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在java中缩放多页TIFF图像

    我想更改多页 TIFF 图像的高度 因此我使用下面的代码片段来缩放它 但它只返回 tiff 文件的第一页 我猜它会将其转换为 JPEG 图像 如何保留文件的所有页面 public static byte scale byte fileDat
  • 转置矩阵存储在一维数组中,无需使用额外的内存[重复]

    这个问题在这里已经有答案了 可能的重复 矩阵的就地转置 https stackoverflow com questions 9227747 in place transposition of a matrix 最近参加了技术笔试 通过以下问
  • 如何裁剪 JavaFX 图像并调整其大小?

    我正在尝试在 JavaFX 画布上显示非常大的图像 单张图像的分辨率为11980x8365 每个图像都有一个相应的世界文件 我可以使用它来正确定位图像 我的画布尺寸是 800x600 有时我需要在画布上写下整个图像 有时只是其中的一部分 这
  • 高效找到圆和网格的交点

    找到由圆心和半径定义的圆与任意网格的交点的好方法是什么 An illustration of the points I am trying to find 到目前为止我想到的可能的解决方案 找到位于中心 半径之间的所有线 对于每条线计算交点
  • 如何找到权重为 1、0、-1 且成本精确为 0 的多维路径

    我得到了一个有向图 其中有 n 个节点和边 向量的权重 每个向量的长度为 m 为数字 1 0 1 我想找到从一个节点到另一个节点 我们可以多次访问节点 的任何路径 或者说这样的路径不存在 使其权重之和等于仅由零组成的向量 我正在考虑暴力回溯
  • 将阿拉伯语文本导出为图像

    我有一堆 UTF 8 格式的阿拉伯文本 我尝试显示此设备的设备不支持显示阿拉伯语文本 因此 我需要将文本转换为图像 我想将每行文本保存为具有特定宽度的图像 我还需要使用特定的字体 做这个的最好方式是什么 有人知道这里有一个有用的工具吗 到目
  • 高效编写航空公司路由算法

    Given 航班数据库 出发城市 到达城市 出发时间 到达时间 问题 如果出发时间不重要 那么在两个城市之间列出服务的最有效算法是什么 考虑到我们想要最小化中途停留时间 但仍高于标称最小值 即 20 分钟 并最小化中途停留次数 如果有直达航
  • 这些加密算法有什么区别?

    两者有什么区别MCRYPT RIJNDAEL 128 MCRYPT RIJNDAEL 256 MCRYPT BLOWFISH等等 哪一种最适合网络数据传输 Rijandel 是 AES 的另一个名称 AES 是当前的 一个好的标准 算法 数
  • 如何有效地从连续字符串中提取文字单词? [复制]

    这个问题在这里已经有答案了 可能的重复 如何将没有空格的文本拆分为单词列表 https stackoverflow com questions 8870261 how to split text without spaces into li
  • 拉伸数组

    我有一个形成曲线的样本向量 假设其中有 1000 个点 如果我想将其拉伸到填充 1500 个点 给出不错结果的最简单算法是什么 我正在寻找一些只有几行 C C 的东西 我总是想增加向量的大小 并且新向量可以是当前向量大小的 1 1 倍到 5
  • OpenCV - 我需要将彩色图像插入黑白图像并且

    我用以下代码将黑白图像插入彩色图像 没问题 face grey cv cvtColor face cv COLOR RGB2GRAY for row in range 0 face grey shape 0 for column in ra
  • 通过 PhoneGap (iOS) 上传后图像横向/上下颠倒

    不知道是什么原因造成的 但是当我通过以下方式将一些图像上传到远程服务器时FileTransfer http docs phonegap com en 1 0 0 phonegap file file md html FileTransfer

随机推荐

  • INVALID_STATE_ERR:DOM 异常 11

    我正在开发一个简单的辅助类来使用 XmlHttpRequest 发送请求 代码如下 但我无法让它发挥作用 例如 在 google chrome 中 我收到错误INVALID STATE ERR DOM Exception 11在其他浏览器上
  • 子进程命令的实时输出

    我使用 python 脚本作为流体动力学代码的驱动程序 当需要运行模拟时 我使用subprocess Popen要运行代码 请收集输出stdout and stderr into a subprocess PIPE 然后我可以打印 并保存到
  • 如果文本太长,如何自动显示工具提示?

    在 Windows 应用商店应用程序中 我有以下 TextBlock
  • 为什么 cmd.exe 在 64 位计算机上具有不同的错误级别行为?

    如果我制作一个名为 temp bat 的批处理脚本 例如 其中包含 exit b 1 当我以各种方式运行它时 我在 32 位 XP 系统和 64 位 XP 系统上得到不同的行为 在 32 位上 gt temp bat gt echo ERR
  • 如何在没有 Manifest.mbdx 的 iOS 5.0 beta 2 中解析 Manifest.mbdb 文件

    我有一个用 iOS 5 beta2 还有 iTunes 10 5 beta 制作的备份 但令我惊讶的是 它不包含 mbdx 文件 The mbdb文件看起来与以前的格式相同 如何匹配文件 ID 和文件名而不需要Manifest mbdx 备
  • PATH 中的其他脚本

    我尝试使用 Homebrew 在 OS X 10 7 5 上安装 Rails 并继续收到以下警告 我已经尝试了很多次更改 PATH 以排除 Python 目录 修改 bash profile 但我什至不确定这就是导致警告的原因 如果这是严重
  • 自定义验证器触发但它不会更新 ValidationSummary

    您好 我正在开发一个自定义表单字段验证器 似乎自定义验证器正在工作 不允许它继续到下一页 但它不会更新验证摘要 也不会显示我的星号和标签 已经变得可见 我在同一字段上还有其他验证器 例如RequiredFieldValidator 我的 V
  • 沉默樱桃

    我有一个cherrypy 服务器将xml 文件分发到网页 当我的服务器运行时 cherrypy 会为已请求的每个网页提供日志 并注明时间戳和网址 对于典型使用来说 这是一个相当不错的功能 但是当请求达到每秒超 过 10 个请求时 日志可能会
  • 推后选项卡消失 ionic 3

    我的标签在使用后消失this navCtrl push NamePage 看不懂 需要使用 ViewChild或者其他功能 我已经设定tabsHideOnSubPages on false in 应用程序模块 ts 例子 https git
  • jinja2 从模板加载模板文件

    有没有办法可以从另一个模板文件中加载 jinja2 模板 就像是 render template path to file html 我有一些想要重用的片段 因此拥有此功能对我来说很重要 include file 做这个 请参阅jinja2
  • Jupyter 密码未经过哈希处理

    当我尝试设置 jupyter 笔记本密码时 打开 jupyter notebook config json 文件时没有获得密码哈希 这是 json 文件的输出 NotebookApp password argon2 argon2id v 1
  • 在不同网站应用程序之间共享 ASP.NET .ascx 控件的最佳方式?

    假设 IIS 中有 2 个不同的 ASP NET 应用程序 此外 您还希望在这两个应用程序之间共享一些 ASCX 控件 创建 用户控件库 的最佳方法是什么 以便您可以在两个应用程序中使用相同的控件实现 而不必重复代码 控件有 ASCX 后面
  • ASP.NET Web API 记录入站请求内容

    我正在尝试注销 Web API 请求内容 即 json 字符串 我实现了一个 ITraceWriter 类 example http www asp net web api overview testing and debugging tr
  • 如何在单个 ssh 命令中使用 bash $(awk)?

    我正在尝试执行一个命令ssh包含首先执行的 子代码 或 子代码 我一直使用它 但我不知道其正式名称 但在目标服务器上 为了便于讨论 假设这是我要使用的命令 当然这可以通过hostname 但这只是一个简化的示例 其中包含我想要使用的所有格式
  • 如何评估gcc格式-溢出检查大小72

    我的示例代码 t c include
  • Firebase 推送通知不适用于 TestFlight/adHoc 版本

    我开发了一个带有推送通知的应用程序 我将其上传到 AppStore 一切正常 通知确实到达了 我现在已经更新了应用程序 以便在用户点击通知时打开网址 在调试模式下使用通过电缆连接的设备进行测试时 一切正常 问题是 如果我通过 TestFli
  • Android - 卸载时删除 SD 卡上的文件

    我的应用程序在安装时从服务器下载一些多媒体文件 我这样做是为了节省应用程序的大小空间 但是 这种方法的缺点是 当卸载应用程序时 它不会删除这些文件 我看过报道说这是可能的 但我似乎无法让它发挥作用 有没有办法在卸载时执行此操作 或者我应该忘
  • C# - 装箱/拆箱/类型转换整数问题。我不明白

    我很难理解这一点 考虑以下示例 protected void Page Load object sender EventArgs e No surprise that this works Int16 firstTest Convert T
  • 如何在反应本机中获取文件夹大小和长度

    如何获取文件夹大小和文件夹中文件的数量 我尝试使用react native fs readDir let pat2 RNFS DocumentDirectoryPath myFolder RNFS readDir pat2 then res
  • 洪水填充算法 - 忽略边缘

    到目前为止 我已经实现了洪水填充算法 我想调整它 这样它就可以去掉边缘 为了演示这一点 我上传了一张图片 图1是我要修改的图像 图 3 是我的算法应该做的事情 图2是我当前的结果 所以在这种情况下 targetColor 是白色 repla