【halcon】write_image 图片保存

前言

write_image 是一个可以用来保存图片的算子,可以将Image对象保存成各种格式的图片。还可以对图片进行压缩。

正文

参数:

  1. Image(输入对象): 输入图像或输入图像的数组。支持的像素类型包括byte、direction、cyclic、int1、complex、int2、uint2、vector_field、int4、int8和real。

  2. Format(输入控制): 要保存图像的图形格式。支持的格式包括:

    • 'tiff','bigtiff':TIFF格式。
    • 'bmp':Windows-BMP格式。
    • 'jpeg':JPEG格式。
    • 'jp2':JPEG-2000格式。
    • 'jpegxr':JPEG-XR格式。
    • 'png':PNG格式。
    • 'hobj':HALCON Iconic Object(HOBJ)格式。
    • 'ima':HALCON格式。
  3. FillColor(输入控制): 不属于图像域(区域)的像素的填充灰度值。对于灰度值图像,必须传递0(黑色)到255(白色)之间的值。对于RGB彩色图像,RGB值可以直接传递为十六进制值,例如,对于黄色背景,可以传递0xffff00(红=255,绿=255,蓝=0)。

  4. FileName(输入控制): 图像文件的名称,包括文件扩展名。具体的扩展名取决于所选择的图形格式。

支持的格式:

  • TIFF格式:

    • 支持所有HALCON像素类型。
    • 可以使用'deflate [num]'、'jpeg [num]'、'lzw'和'packbits'进行压缩。
    • 可以将图像域以压缩形式存储为'mask'(默认设置)或作为附加的alpha通道存储为'alpha'。
  • BMP格式:

    • 仅支持像素类型为byte的图像。
    • 仅支持包含一个通道(灰度值图像)或三个通道(RGB图像)的图像。
  • JPEG格式:

    • 仅支持像素类型为byte的图像。
    • 可以指定质量值确定的压缩率,例如,'jpeg 30'。
  • JPEG-2000格式:

    • 支持lossless和lossy压缩。
    • 可以指定决定压缩率的质量值,例如,'jp2 40'。
  • JPEG-XR格式:

    • 支持lossless和lossy压缩。
    • 可以指定决定压缩率的质量值,例如,'jpegxr 30'。
  • PNG格式:

    • 支持lossless压缩。
    • 可以指定0到9的压缩级别,或使用字符串'best'、'fastest'和'none'进行选择。
  • HALCON Iconic Object(HOBJ)格式:

    • 支持所有HALCON图像类型。
  • HALCON格式:

    • 现在是遗留的格式,建议使用HOBJ格式。

执行信息:

  • 多线程类型: 可重入(可以与非独占操作同时运行)。
  • 多线程范围: 全局(可以从任何线程调用)。
  • 自动并行化: 在元组级别上自动并行化。

返回结果:

如果参数值正确,write_image 操作符将返回值2(H_MSG_TRUE)。否则,将引发异常。

问答环节

如果我想保存成png格式如何实现压缩?

要将图像保存为PNG格式并实现压缩,你可以在 write_image 操作符的 Format 参数中指定压缩级别。压缩级别可以是介于0和9之间的整数,其中0表示无压缩,9表示最佳压缩。此外,你还可以使用一些字符串来选择压缩级别,如'best'表示最佳压缩,'fastest'表示最快速度,'none'表示无压缩。

以下是将图像保存为PNG格式并进行压缩的示例:

cpp 复制代码
// 将图像保存为PNG格式并设置压缩级别
write_image(Image, 'png 5', 0, 'output.png');

在上述示例中,'png 5' 指定了压缩级别为5。你可以根据需要调整压缩级别。如果你希望实现最佳压缩,可以将字符串设置为 'png best'

cpp 复制代码
// 将图像保存为PNG格式并使用最佳压缩级别
write_image(Image, 'png best', 0, 'output.png');

请注意,使用更高的压缩级别可能会导致保存过程变慢,因此你可能需要权衡压缩率和性能。

JPEG 如何保存呢?

当你想将图像保存成 JPEG 格式时,可以使用 write_image 操作符,并设置格式参数为 'jpeg',同时可以通过指定质量参数来调整 JPEG 的压缩质量。以下是详细介绍:

操作符签名

cpp 复制代码
write_image(Image, 'jpeg [quality]', FillColor, 'output.jpg');
  • Image: 待保存的图像或图像数组。
  • 'jpeg [quality]': JPEG 格式字符串,quality 参数可选,用于指定压缩质量。quality 的范围一般为 0 到 100,值越大表示质量越高,文件大小越大。例如,'jpeg 90' 表示压缩质量为 90。
  • FillColor: 用于指定图像外部区域的填充颜色。对于 JPEG,这通常不太影响,可以设置为 0。
  • 'output.jpg': 输出文件的名称和路径。

示例

cpp 复制代码
// 保存为 JPEG 格式,压缩质量为 90
write_image(Image, 'jpeg 90', 0, 'output.jpg');

注意事项

  1. 压缩质量: 质量设置为 100 表示最高质量,0 表示最低质量。适当的质量设置可以在保持图像质量的同时减小文件大小。
  2. 压缩速度和文件大小: 选择较高的质量通常会导致较大的文件大小,同时保存时间可能稍长。在速度和文件大小之间需要平衡,具体取决于应用需求。
  3. 颜色损失: JPEG 是有损压缩格式,会引入一定程度的颜色损失。这种损失在较高的质量设置下会减小,但不会完全消除。

根据你的具体需求,可以根据测试和实验来选择合适的质量参数和其他选项。

哪一种保存的时间比较快呢?

这里我写了一个程序进行测试:

csharp 复制代码
 HObject img;
 HOperatorSet.ReadImage(out img, "1.tif");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "png fastest", 0, "p1");
 stopwatch.Stop();
 Debug.WriteLine($"png fastest: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "png bset", 0, "p2");
 stopwatch.Stop();
 Debug.WriteLine($"png bset: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "tiff", 0, "t"); 
 stopwatch.Stop();
 Debug.WriteLine($"tiff: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "bmp", 0, "b"); 
 stopwatch.Stop();
 Debug.WriteLine($"bmp: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "jpeg", 0, "j1");
 stopwatch.Stop();
 Debug.WriteLine($"jpeg: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "jpeg 30", 0, "j2");
 stopwatch.Stop();
 Debug.WriteLine($"jpeg 30: {stopwatch.ElapsedMilliseconds}");

 stopwatch.Restart();
 HOperatorSet.WriteImage(img, "jpeg 90", 0, "j3");
 stopwatch.Stop();
 Debug.WriteLine($"jpeg 90: {stopwatch.ElapsedMilliseconds}");

读取的是一张56M图片,是黑白的,执行结果如下(单位ms):

png fastest: 1247

png bset: 3421

tiff: 144

bmp: 179

jpeg: 126

jpeg 30: 100

jpeg 90: 183

最快的是 jpeg 压缩质量为30的时候。虽然质量只有30,但一眼看上去也没啥区别,不过大小是小的真的多(不愧是是有损压缩!)。

当然还有其他格式,我没有一一去测试,大家可以自行尝试!

相关推荐
鸿喵小仙女22 分钟前
C# WPF读写STM32/GD32单片机Flash数据
stm32·单片机·c#·wpf
一个不正经的林Sir25 分钟前
C#WPF基础介绍/第一个WPF程序
开发语言·c#·wpf
码农君莫笑11 小时前
使用blazor开发信息管理系统的应用场景
数据库·信息可视化·c#·.net·visual studio
可喜~可乐13 小时前
C# WPF开发
microsoft·c#·wpf
666和77717 小时前
C#的单元测试
开发语言·单元测试·c#
小码编匠18 小时前
WPF 星空效果:创建逼真的宇宙背景
后端·c#·.net
向宇it21 小时前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
yngsqq21 小时前
一键打断线(根据相交点打断)——CAD c# 二次开发
windows·microsoft·c#
TENET信条1 天前
day53 第十一章:图论part04
开发语言·c#·图论
anlog1 天前
C#在自定义事件里传递数据
开发语言·c#·自定义事件