基于二值化图像转GCode的斜向扫描实现

  • 基于二值化图像转GCode的斜向扫描实现
    • 什么是斜向扫描
    • 斜向扫描代码示例

基于二值化图像转GCode的斜向扫描实现

什么是斜向扫描

激光雕刻斜向扫描

在激光雕刻中,斜向扫描(Diagonal Scanning)是一种雕刻技术,其中激光头沿着对角线方向来回移动,而不是沿着水平或垂直方向。这种扫描方式的目的是在雕刻过程中更均匀地覆盖整个图像表面,从而提高雕刻的效果。

斜向扫描的过程包括以下步骤:

  1. 起始位置: 激光头移动到图像的起始位置。

  2. 斜向移动: 激光头沿对角线方向开始移动,逐行或逐列地刻蚀图像表面。与水平或垂直扫描不同,激光头沿着斜线移动,使得刻蚀路径更加均匀。

  3. 返回: 当一行或一列刻蚀完成后,激光头返回到图像的另一侧,准备进行下一行或下一列的刻蚀。

  4. 循环重复: 重复以上步骤,直到整个图像都被刻蚀完成。

相比于传统的水平或垂直扫描,斜向扫描能够减少在图像表面上可能出现的痕迹或线条,使得雕刻效果更为平滑和均匀。这对于一些需要高质量表面的雕刻应用,如艺术品或装饰品制作,具有重要意义。

选择采用斜向扫描还是其他扫描方式通常取决于具体的雕刻需求和设计目标。一些激光雕刻机允许用户根据实际情况选择不同的扫描方式以获得最佳的雕刻效果。

斜向扫描代码示例

#include <optional>
#include <string>
#include <print>
#include <format>
#include <vector>
#include <fstream>
#include <ranges>struct G0 {std::optional<float> x, y;std::optional<int> s;std::string toString() {std::string command = "G0";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}explicit operator std::string() const {std::string command = "G0";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}
};struct G1 {std::optional<float> x, y;std::optional<int> s;std::string toString() {std::string command = "G1";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}explicit operator std::string() const {std::string command = "G1";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}
};inline bool ExportGCode(const std::string &fileName, std::vector<std::string> &&gcode) {std::fstream file;file.open(fileName, std::ios_base::out | std::ios_base::trunc);if(!file.is_open()) {return false;}for(auto &&v: gcode | std::views::transform([](auto item) { return item += "\n"; })) {file.write(v.c_str(), v.length());}return true;
}int main() {constexpr int imageWidth  = 10;constexpr int imageHeight = 10;// clang-format off// 假设图像数据,0表示非激光刻蚀部分,1表示进行激光刻蚀的区域constexpr int image[imageWidth][imageHeight] = {{0, 1, 1, 1, 0, 1, 1, 1, 0, 0}, // G0 G1 G1 G1 G0 G1 G1 G1 G0 G0{1, 0, 1, 0, 1, 0, 1, 0, 1, 0},{1, 1, 1, 0, 0, 1, 1, 1, 1, 1},{0, 0, 1, 1, 1, 1, 1, 0, 0, 0},{1, 1, 0, 0, 1, 0, 0, 1, 1, 1},{0, 1, 1, 0, 0, 1, 0, 0, 0, 0},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},{1, 0, 0, 0, 1, 0, 1, 0, 0, 0},{0, 1, 0, 1, 0, 1, 0, 1, 0, 1},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};// clang-format onstd::vector<std::string> command;for(int k = 0; k < imageHeight + imageWidth - 1 /*cond = height + width - 1*/; ++k) {  // 线条数if constexpr (false) {// 单斜向for(int x = std::min(k, imageHeight - 1); x >= 0; --x) {int y = k - x;if(y < imageWidth) {if(auto const value = image[y][x];value) {command.emplace_back(G1 {x, y, 1000});  // 最大激光功率 S=1000} else {command.emplace_back(G0 {x, y, 0});}}}}else {// 双斜向if((k & 1) == 0) {// evenfor(int x = std::min(k, imageHeight - 1); x >= 0; --x) {int y = k - x;if(x < imageHeight && y < imageWidth) {if(auto const value = image[y][x];value) {command.emplace_back(G1 {x, y, 1000});  // 最大激光功率 S=1000} else {command.emplace_back(G0 {x, y, 0});}}}}else {// oddfor(int y = std::min(k, imageWidth - 1); y >= 0; --y) {int x = k - y;if(x < imageHeight && y < imageWidth) {if(auto const value = image[y][x];value) {command.emplace_back(G1 {x, y, 1000});  // 最大激光功率 S=1000} else {command.emplace_back(G0 {x, y, 0});}}}}}}// 导出GCodeExportGCode("gcode.nc",std::move(command));std::println("Export data to gcode.nc");return 0;
}

单向斜向扫描
激光雕刻单斜向扫描

双向斜向扫描
激光雕刻双斜向扫描仿真

上述示例展示了一个10x10的二维图像数据,其中0表示非激光刻蚀部分,1表示进行激光刻蚀的区域。通过遍历图像数据,代码生成了相应的G代码指令序列,用于描述激光头在工件表面的运动路径。

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

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

相关文章

C++面试:表结构设计规范

目录 表结构设计规范 示例 第一个 第二个 1. 合理选择数据类型 2. 使用主键 3. 避免使用NULL 4. 规范命名 5. 规范化 6. 使用索引优化查询 7. 考虑关系完整性 8. 避免过宽的表 9. 预留扩展性 10. 安全性考虑 表结构设计是数据库设计的重要组成部分&#xff0c;它…

编译opencv4.6问题汇总,第三方软件包见我发的资源

win10系统 python3.8.2&#xff0c;cmake-3.15.5-win64-x64&#xff0c;opencv4.6 编译方式见&#xff1a;OpenCV的编译 - 知乎 本文主要总结问题。赠人玫瑰手留余香。 问题1 Problem with installing OpenCV using Visual Studio and CMake (error code: MSB3073) 解决方法…

c# textbox 提示文字

1. 定义提示文字内容 private readonly string RemarkText "最多输入100字"; // 提示文字 2. 添加textbox 焦点事件&#xff0c; 初始化textbox提示文字和字体颜色 public UserControl(){InitializeComponent();tb_Remark.Text RemarkText;tb_Remark.ForeColor…

R语言基础学习-01 (此语言用途小众 用于数学 生物领域 基因分析)

R 语言特点 R 语言环境软件属于 GNU 开源软件&#xff0c;兼容性好、使用免费语法十分有利于复杂的数学运算数据类型丰富&#xff0c;包括向量、矩阵、因子、数据集等常用数据结构代码风格好&#xff0c;可读性强 简单 虽然 R 主要用于统计分析或者开发统计相关的软件&#x…

微信小程序(二十六)列表渲染基础核心

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.列表渲染基础写法 2.外部索引和自身索引 源码&#xff1a; index.wxml <view class"students"><view class"item"><text>序号</text><text>姓名</text…

JUC并发编程

Java 并发编程&#xff08;Java Concurrency&#xff09;是指在 Java 程序中同时进行多个任务的一种编程方式。Java 提供了一套丰富的并发编程工具&#xff0c;其中包括 Java 并发包&#xff08;Java Concurrency Utilities&#xff0c;简称 JUC&#xff09;&#xff0c;用于简…

Unity2D_单向平台

类似空洞骑士 马里奥等各种2D游戏&#xff0c;其中都存在单向平台。 单向平台&#xff1a;角色可以从下穿过平台停在平台上&#xff0c;也可以从平台上按下或往下跳穿过平台 这里用Unity实现角色能跳上平台&#xff0c;也能按’下’穿过平台 平台需要使用Rigidbody2D Collid…

jQuery html的使用

jquery中的html方法可以获取和设置标签的html内容 var $div $("div")// 获取标签div的html内容alert($div.html())console.log($div.html()) .html: 设置标签的html内容&#xff0c;之前的内容会清除&#xff08;只会显示 CSDN&#xff09; // 设置标签的html内容&…

字符串中的单词反转【leetcode】

本题选自leetcode图解算法数据结构一书 你在与一位习惯从右往左阅读的朋友发消息&#xff0c;他发出的文字顺序都与正常相反但单词内容正确&#xff0c;为了和他顺利交流你决定写一个转换程序&#xff0c;把他所发的消息 message 转换为正常语序。 注意&#xff1a;输入字符串…

java学习笔记:java所有关键字汇总、解析及应用

文章目录 一、java的所有关键字汇总、解析及应用1. abstract2. assert3. boolean4. break5. byte6. case7. catch8. char9. class10. const11. continue12. default13. do14. double15. else16. enum17. extends18. final19. finally20. float21. for22. goto23. if24. impleme…

走迷宫-bfs

package Test;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Main {static int N 110,hh 0,tt -1,n,m;static int[][] g new int[N][N]; //用来存储迷宫static int[][] d new int[N][N]; //用来存储d[i…

【C/Python】Gtk部件ListStore的使用

一、C语言 在GTK中&#xff0c;Gtk.ListStore是一个实现了Gtk.TreeModel接口的存储模型&#xff0c;用于在如Gtk.TreeView这样的控件中存储数据。以下是一个简单的使用Gtk.ListStore的C语言示例&#xff0c;该示例创建了一个列表&#xff0c;并在图形界面中显示&#xff1a; …

EasyExcel实现Excel文件导入导出

1 EasyExcel简介 EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 github地址: https://github.com/alibaba/easyexcel 官方文档: https://www.yuque.com/easyexcel/doc/easyexcel Excel解析流程图: EasyExcel读取…

TensorFlow2实战-系列教程11:RNN文本分类3

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 6、构建训练数据 所有的输入样本必须都是相同shape&#xff08;文本长度&#xff0c;…

视网膜长尾数据

视网膜长尾数据 问题&#xff1a;视网膜疾病分类&#xff0c;解法&#xff1a;深度学习模型问题&#xff1a;数据复杂性处理&#xff0c;解法&#xff1a;多任务框架&#xff08;同时处理多种疾病&#xff09;和少量样本学习&#xff08;提高对罕见疾病的识别&#xff09;问题&…

记录解决报错--vue前后端分离,接口401(Unauthorized)

1.场景 前端访问不了后端接口。报错401。 2.解决步骤 ①在页面console.log(111)查看走到代码的位置没有。&#xff08;走到了&#xff0c;没问题&#xff09; ②查看vue.config.js配置。这段配置就是vue访问api的url。&#xff08;没问题&#xff09; devServer: {port: 80…

【Delphi】IDE 工具栏错乱恢复

由于经常会在4K和2K显示器上切换Delphi开发环境(IDE)&#xff0c;导致IDE工具栏错乱&#xff0c;咋样设置都无法恢复&#xff0c;后来看到红鱼儿的博客&#xff0c;说是通过操作注册表的方法&#xff0c;能解决&#xff0c;试了一下&#xff0c;果真好用&#xff0c;非常感谢分…

Java面试架构篇【一览众山小】

文章目录 &#x1f6a1; 简介☀️ Spring&#x1f425; 体系结构&#x1f420; 生命周期 &#x1f341; SpringMVC&#x1f330; 执行流程 &#x1f31c; SpringBoot&#x1f30d; 核心组件&#x1f38d; 自动装配&#x1f391; 3.0升级 &#x1f505; spring Cloud Alibaba&am…

获取依赖aar包的两种方式-在android studio里引入 如:glide

背景&#xff1a;我需要获取aar依赖到内网开发&#xff0c;内网几乎代表没网。 一、 如何需要获取依赖aar包 方式一&#xff1a;在官方的github中下载,耗时不建议 要从开发者网站、GitHub 存储库或其他来源获取 ‘com.github.bumptech.glide:glide:4.12.0’ AAR 包&#xff…

vue使用antv-x6 绘制流程图DAG图(二)

代码&#xff1a; <template><div class"graph-wrap" click.stop"hideFn"><Toobar :graph"graph"></Toobar><!-- 小地图 --><div id"minimap" class"mini-map-container"></div>…