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

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

什么是单向扫描

激光雕刻单向扫描

在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。

具体而言,单向扫描的过程通常包括以下步骤:

  1. 横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。

  2. 纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。

  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 on

    std::vector<std::string> command;
    for(int y = 0; y < imageHeight; ++y) {
        command.emplace_back(G0 {0, y, 0});
        for(int x = 0; x < imageWidth; ++x) {
            if(auto const value = image[y][x];value) {
                command.emplace_back(G1 {x, std::nullopt, 1000});  // 最大激光功率 S=1000
            } else {
                command.emplace_back(G0 {x, std::nullopt, 0});
            }
        }
    }

    // 导出GCode
    ExportGCode("gcode.nc",std::move(command));
    std::println("Export data to gcode.nc");
    return 0;
}

激光雕刻单向扫描仿真

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
图像信息嵌入与提取可以通过使用最低有效位(LSB)的方法来实现。以下是一个简单的Python代码示例,可以将消息嵌入到图像中并从图像中提取隐藏的消息。 ```python from PIL import Image def embed_message(img_path, message): # 打开载体图像 img = Image.open(img_path) pixels = img.load() width, height = img.size # 将每个字符的二进制编码嵌入到RGB通道的最低有效位中 char_count = 0 for y in range(height): for x in range(width): r, g, b = pixels[x, y] if char_count < len(message): char_code = ord(message[char_count]) r = (r & 0xFE) | ((char_code >> 7) & 0x01) g = (g & 0xFE) | ((char_code >> 6) & 0x01) b = (b & 0xFE) | ((char_code >> 5) & 0x01) char_count += 1 pixels[x, y] = (r, g, b) # 保存修改后的图像 img.save("embedded.png") def extract_message(img_path): # 打开含有隐藏信息的图像 img = Image.open(img_path) pixels = img.load() width, height = img.size # 从RGB通道的最低有效位中提取出每个字符的二进制编码 message = "" char_count = 0 for y in range(height): for x in range(width): r, g, b = pixels[x, y] if char_count < 8: char_code = ((r & 0x01) << 7) | ((g & 0x01) << 6) | ((b & 0x01) << 5) message += chr(char_code) char_count += 1 else: return message return message ``` embed_message()函数将消息嵌入到指定的图像中,而extract_message()函数从图像中提取隐藏的消息。这两个函数都需要一个图像文件路径作为输入,并且embed_message()函数还需要一个字符串消息作为输入。在嵌入和提取过程中,每个字符的二进制编码都嵌入到RGB通道的最低有效位中,然后可以从中提取出隐藏的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cheungxiongwei.com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值