激光雕刻优化:利用RLE压缩技术提高雕刻效率与节省能源成本

激光雕刻

  • 什么是 RLE ?
  • RLE 在激光雕刻应用
  • 实现代码:
  • 总结

什么是 RLE ?

RLE 是 Run-Length Encoding(游程长度编码)的缩写。这是一种数据压缩技术,它通过减少连续重复的数据来减小文件的大小。RLE 在图像处理、无损压缩和数据传输等领域中都有广泛应用。基本上,RLE 将连续相同的数据值(或称为“游程”)替换为一个值和一个计数值的组合。这样的编码在一些情况下非常有效,特别是当数据中存在大量重复的连续值时。

在图像处理和存储中,RLE 可以用于将图像数据编码为更紧凑的格式,从而节省存储空间并加快数据传输速度。

例如,考虑一个简单的黑白图像,其中大部分区域都是连续的白色像素。在没有压缩的情况下,每个像素都需要单独存储其值,这会占用大量空间。但是,如果使用 RLE,可以将连续的白色像素游程编码为一个值(表示白色)和一个计数值(表示连续的像素数量),从而实现数据压缩。

假设有一行像素数据:FFFFFFBBBBBFFFFFFFFF. 在 RLE 编码下,这行像素可以表示为 6F5B10F,其中 6F 表示连续的六个白色像素,5B 表示连续的五个黑色像素,10F 表示连续的十个白色像素。

通过这种方式,可以大大减小图像的存储空间,特别是对于包含大量相同值的图像。在传输或存储图像时,RLE 编码可以在保持图像质量的同时显著减少所需的存储空间或传输带宽。

RLE 在激光雕刻应用

在激光雕刻应用中,RLE(Run-Length Encoding)可以用于优化图像或矢量图形的数据传输和处理。激光雕刻通常需要将图像或图形转换为适合激光刻录机的指令,这些指令通常以一种称为 G-code 的格式表示。

RLE 可以在以下方面对激光雕刻应用进行优化:

  1. 数据压缩:原始图像或图形可能包含大量相同或类似的连续像素或路径。使用 RLE 可以将这些连续的像素或路径编码为游程,并用更简洁的方式表示,从而减小传输或存储的数据量。
  2. 路径优化:在将图像转换为激光刻录机的指令时,RLE 可以帮助优化路径。通过识别和合并相邻的线段或轮廓,可以减少激光头在工作区域内的移动次数,从而提高雕刻效率并减少制作时间。
  3. 减少机器负载:在处理大型图像或复杂图形时,RLE 可以减少激光刻录机的负载。通过减少传输到激光刻录机的指令数量,可以降低激光刻录机的计算和执行负荷,提高整体效率和性能。

实现代码:

CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(rle)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/execution-charset:utf-8>")

add_executable(rle main.cpp)

target_precompile_headers(untitled1 PRIVATE <vector> <print>)

main.cpp

#include <vector>
#include <print>

struct RLE {
    int pos;    // 位置
    int value;  // 像素的值
    int length; // 像素长度
};

// LeftToRight
std::vector<RLE> buildRLELTR(const std::vector<int> &input) {
    std::vector<RLE> rle;
    int count = 1;

    for (int i = 0; i < input.size(); ++i) {
        if (i + 1 < input.size() && input[i] == input[i + 1]) {
            ++count;
        } else {
            RLE rleElement;
            rleElement.pos = i - count + 1;
            rleElement.value = input[i];
            rleElement.length = count;
            rle.push_back(rleElement);
            count = 1;
        }
    }

    return rle;
}

// RightToLeft
std::vector<RLE> buildRLERTL(const std::vector<int> &input) {
    std::vector<RLE> rle;
    int count = 1;

    for (int i = input.size() - 1; i >= 0; --i) {
        if (i - 1 >= 0 && input[i] == input[i - 1]) {
            ++count;
        } else {
            RLE rleElement;
            rleElement.pos = i + 1;
            rleElement.value = input[i];
            rleElement.length = count;
            rle.push_back(rleElement);
            count = 1;
        }
    }
    return rle;
}

std::vector<RLE> buildRLE(const std::vector<int> &input, bool rightToLeft = false) {
    std::vector<RLE> rle;
    int count = 1;

    int start = rightToLeft ? input.size() - 1 : 0;
    int end = rightToLeft ? -1 : input.size();
    int step = rightToLeft ? -1 : 1;

    for (int i = start; i != end; i += step) {
        if ((i + step >= 0 && i + step < input.size()) && input[i] == input[i + step]) {
            ++count;
        } else {
            RLE rleElement;
            rleElement.pos = i - (rightToLeft ? count - 1 : count) * step + 1;
            rleElement.value = input[i];
            rleElement.length = count;

            if (rightToLeft) {
                rle.insert(rle.begin(), rleElement);
            } else {
                rle.push_back(rleElement);
            }

            count = 1;
        }
    }

    return rle;
}

bool buildRLELTR(const std::vector<int> &input, int &i, RLE &rle) {
    int count = 1;
    for (; i < input.size(); ++i) {
        if (i + 1 < input.size() && input[i] == input[i + 1]) {
            ++count;
        } else {
            rle.pos = i - count + 1;
            rle.value = input[i];
            rle.length = count;
            ++i;
            return true;
        }
    }
    return false;
}

bool buildRLERTL(const std::vector<int> &input, int &i, RLE &rle) {
    int count = 1;
    for (; i >= 0; --i) {
        if (i - 1 >= 0 && input[i] == input[i - 1]) {
            ++count;
        } else {
            rle.pos = i;
            rle.value = input[i];
            rle.length = count;
            i--;
            return true;
        }
    }
    return false;
}

int main() {
    // clang-format off
    // 假设以下二维数组是灰度图像预处理后的激光强度映射,通过构建 RLE 数据结构,最后根据 RLE 生成 GCode 文本,可以实现数据压缩效果。
    using grayline = std::vector<int>;
    std::vector<grayline> array = {
        {925, 925, 925, 921, 917, 917, 898, 902, 906, 917},
        {917, 917, 917, 898, 890, 902, 902, 914, 925, 921},
        {914, 921, 925, 906, 898, 902, 902, 906, 910, 914},
        {910, 906, 902, 898, 886, 875, 917, 921, 906, 914},
        {914, 898, 906, 910, 898, 890, 894, 886, 882, 878},
        {914, 898, 906, 910, 898, 890, 894, 886, 882, 878},
        // 001, 002, 003, 004, 005, 006, 007, 008, 009, 010},
    };
    // clang-format on

    int i;
    RLE rle;

    i = 0;
    while (1) {
        auto ret = buildRLELTR(array[0], i, rle);
        if (ret) {
        	// toCode
            // X{rle.pos+rle.length} S{rle.value}
            std::println("# {:3} {:3} {:3}", rle.pos, rle.value, rle.length);
        } else {
            break;
        }
    }

    std::println("");

    i = array[1].size() - 1;
    ;
    while (1) {
        auto ret = buildRLERTL(array[1], i, rle);
        if (ret) {
            std::println("# {:3} {:3} {:3}", rle.pos, rle.value, rle.length);
        } else {
            break;
        }
    }

    std::println("==========================");

    {
        std::vector<RLE> rle = buildRLE(array[0], false);
        // left to right build
        for (const RLE &element: rle) {
            std::println("{:3} {:3} {:3}", element.pos, element.value, element.length);
        }
    }
    std::println("");
    {
        std::vector<RLE> rle = buildRLE(array[1], true);
        // implment right to left build
        for (const RLE &element: rle) {
            std::println("{:3} {:3} {:3}", element.pos, element.value, element.length);
        }
    }

    return 0;
}

总结

综上所述,RLE 在激光雕刻应用中可以通过数据压缩、路径优化和减少机器负载等方式提高效率并降低成本。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VS调试技巧

1. 什么是bug bug本意是“昆⾍”或“⾍⼦”&#xff0c;现在⼀般是指在电脑系统或程序中&#xff0c;隐藏着的⼀些未被发现的缺陷或 问题&#xff0c;简称程序漏洞。 “Bug” 的创始⼈格蕾丝赫柏&#xff08;Grace Murray Hopper&#xff09;&#xff0c;她是⼀位为美国海军⼯…

C 语言文件输入/输出(I/O)函数大全

C 语言文件输入/输出&#xff08;I/O&#xff09;函数大全 1. fopen() 函数2. fclose() 函数3. fread() 函数4. fwrite() 函数5. fseek() 函数6. ftell() 函数7. rewind() 函数8. feof() 函数9. ferror() 函数10. clearerr() 函数 &#x1f60a; C 语言文件输入/输出&#xf…

gradio图像复原界面改进

图像复原界面展示需要输入图像和复原图像在界面的清晰对比&#xff0c;修改两张图像为同样大小。 默认情况&#xff1a; intreface代码如下&#xff1a; interface gr.Interface(fnrestore, # 要调用的函数inputs[gr.Image(label"输入图像")], # 第一个输入&am…

AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

测试平台开发:Django开发实战之注册界面实现(上)

实现注册功能&#xff0c;大概包括以下几个步骤 1、设计ui ##字段 通过看数据库里面的user表里面的字段&#xff0c;可以大概知道需要几个字段&#xff1a; emailusernamepasswordpassword_confirm 生成简单的ui界面&#xff0c;复制这个html代码 然后在项目路径下面创建一…

22_Scala集合Seq

文章目录 Seq序列1.构建集合2.List集合元素拼接&&集合拼接3.可变Seq&&List3.1 ListBuffer创建3.2 增删改查3.3 相互转化 Appendix1.Scala起别名2.Seq底层3.关于运算符操作: :4.空集合的表示 Seq序列 –Seq表示有序&#xff0c;数据可重复的集合 1.构建集合 …

整体安全保障服务方案包括哪些方面?

整体安全保障服务方案是一套综合性的措施&#xff0c;旨在保护企业的网络、数据和资源免受各种威胁。主要包含检测、加固、应急保障、安全运营、攻防演练等多项核心能力与服务。 ​安全狗通过专业团队、工具以及专业运营流程&#xff0c;提出了新一代整体安全保障思路&#xff…

开源代码分享(28)-含分布式光伏的配电网集群划分和集群电压协调控制

参考文献&#xff1a; [1] Chai Y , Guo L , Wang C ,et al.Network Partition and Voltage Coordination Control for Distribution Networks With High Penetration of Distributed PV Units[J].IEEE Transactions on Power Systems, 2018:3396-3407.DOI:10.1109/TPWRS.2018…

【深度学习】实验1 波士顿房价预测

波士顿房价预测 代码 import numpy as np import matplotlib.pyplot as pltdef load_data():# 1.从文件导入数据datafile D:\Python\PythonProject\sklearn\housing.datadata np.fromfile(datafile, sep )# 每条数据包括14项&#xff0c;其中前面13项是影响因素&#xff0c…

长方形盒子能容纳定宽的长方形物体最大长度

问题 已知长方形盒子长度a和宽度b&#xff0c;放入一宽度w的长方形物体&#xff0c;求长方形物体最大长度L。 答案 MS Excel公式如下&#xff08;其中B1a&#xff0c;B2b&#xff0c;B3w&#xff09;&#xff1a; L SQRT(B1^2B2^2)-B1*B2*B3*2/(B1^2B2^2)注意 当求得 L ≤…

时间复杂度与空间复杂度(上篇)

目录 前言时间复杂度 前言 算法在运行的过程中要消耗时间资源和空间资源 所以衡量一个算法的好坏要看空间复杂度和时间复杂度&#xff0c; 时间复杂度衡量一个算法的运行快慢 空间复杂度是一个算法运行所需要的额外的空间 一个算法中我们更关心的是时间复杂度 时间复杂度 时…

使用idea管理docker

写在前面 其实idea也提供了docker的管理功能&#xff0c;比如查看容器列表&#xff0c;启动容器&#xff0c;停止容器等&#xff0c;本文来看下如何管理本地的docker daemon和远程的dockers daemon。 1&#xff1a;管理本地 双击shift&#xff0c;录入service&#xff1a; …

24年审计师报名时间汇总所需材料提前准备

2024审计师报名本周开始&#xff08;5月10日起&#xff09;&#xff0c;各地报名时间不一&#xff0c;报名指南整理好了&#xff01; ✅全国报名时间汇总报名费用资格审核&#xff1a;P1~P2。 ✅2024年审计师考试科目&#xff1a; 《审计相关基础知识》和《审计理论与实务》 ✅…

如何创建微信小程序?只需3步完成小程序制作

微信&#xff0c;中国最大的社交媒体应用程序&#xff0c;几个月前推出了微信小程序&#xff0c;这一神奇的功能立即大受欢迎。这些小程序让在中国注册的商业实体所有者创建一个小程序来与微信用户互动。这些小程序不需要在用户手机上进行任何安装&#xff0c;只需通过微信应用…

HP Z620 服务器打开VTx虚拟技术

在使用Virtual Box的时候&#xff0c;虚拟主机启动报错&#xff1a;提示需要VTx。于是到bios里面去设置VTx。 这里有个小坑&#xff0c;就是HP 的bios配置里面&#xff0c;VTx不在常规的“System Configuration”、“Advanced”等地方&#xff0c;而是在“Security”菜单里&…

关于2024年上半年软考考试批次安排的通告

按照《2024年计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作安排及有关事项的通知》&#xff08;计考办〔2024〕1号&#xff09;文件精神&#xff0c;结合各地机位实际&#xff0c;现将2024年上半年计算机软件资格考试有关安排通告如下&#xff1a; 一、考…

【排序算法】之冒泡排序

一、算法介绍 冒泡排序&#xff08;Bubble Sort&#xff09;是一种基础的排序算法&#xff0c;它的主要思想是通过重复遍历待排序的列表&#xff0c;比较每对相邻的元素并根据需要交换它们&#xff0c;使得每一遍遍历都能将未排序的最大&#xff08;或最小&#xff09;元素“冒…

RH 414膜电位荧光探针,161433-30-3,具有出色的荧光性质和高度专业化的反应原理

一、试剂信息 名称&#xff1a;RH 414膜电位荧光探针CAS号&#xff1a;161433-30-3结构式&#xff1a; 二、试剂内容 RH 414膜电位荧光探针是一种基于荧光共振能量转移&#xff08;FRET&#xff09;技术的荧光染料&#xff0c;具有出色的荧光性质和高度专业化的反应原理。…

Cordova 12 Android 不支持 http 原因探索

最近在升级 Cordova 到最新版本&#xff0c;升级完成后发现无法请求网络&#xff0c;研究了两次最终发现解决方案。 发现控制台中有日志输出&#xff0c;提示当前是 https &#xff0c;无法直接访问 http。 [INFO:CONSOLE(225)] "Mixed Content: The page at https://lo…

如何更好地使用Kafka? - 运行监控篇

要确保Kafka在使用过程中的稳定性&#xff0c;需要从kafka在业务中的使用周期进行依次保障。主要可以分为&#xff1a;事先预防&#xff08;通过规范的使用、开发&#xff0c;预防问题产生&#xff09;、运行时监控&#xff08;保障集群稳定&#xff0c;出问题能及时发现&#…
最新文章