当前位置: 首页 > news >正文

图片处理OpenCV IMDecode模式说明【生产问题处理】

OpenCV IMDecode模式说明【生产问题处理】

1 前言

今天售后同事反馈说客户使用我们的图片处理,将PNG图片处理为JPG图片之后,变为了白板。

  • 我们图片处理使用的是openCV来进行处理

2 分析

2.1 图片是否损坏:非标准PNG头部

于是,马上写了一个demo尝试本地复现,结果复现概率是:必现。

package mainimport ("fmt""gocv.io/x/gocv"_ "image/jpeg"_ "image/png""io""os"
)func main() {params := []int{gocv.IMWriteJpegQuality, 1}srcFile, err := os.Open("/Users/xxx/GolandProjects/xxx/image-encoder/demo/quality/3.png")if err != nil {fmt.Printf("%v", err)return}defer srcFile.Close()imageBuf, err := io.ReadAll(srcFile)if err != nil {fmt.Printf("%v", err)return}mat, err := gocv.IMDecode(imageBuf, gocv.IMReadUnchanged)if err != nil {fmt.Printf("%v", err)return}buf, err := gocv.IMEncodeWithParams(gocv.JPEGFileExt, mat, params)//buf, err := gocv.IMEncodeWithParams(gocv.JPEGFileExt, mat, params)if err != nil {fmt.Printf("%v", err)return}os.WriteFile("/Users/xxx/GolandProjects/xxx/image-encoder/demo/quality/33.jpg", buf.GetBytes(), os.ModePerm)if err != nil {fmt.Printf("%v", err)return}println("DONE.....")
}

接着尝试将我本地其他的PNG图片转换为JPG,发现可以转换成功。表示这个代码是可以将PNG转换为JPG的。

于是,开始排查是否是客户图片有破损,比如图片的文件头已经损坏,导致它不是一个标准的PNG图片。

在这里插入图片描述

通过查阅资料后发现PNG的头部为89 50 4E 47 0D 0A 1A 0A
在这里插入图片描述

package mainimport ("encoding/hex""fmt""os"
)func main() {filePath := "/Users/xsky/GolandProjects/xxx/image-encoder/demo/quality/11.png" // 替换为你的 PNG 图片文件路径file, err := os.Open(filePath)if err != nil {fmt.Println("Error opening file:", err)return}defer file.Close()header := make([]byte, 8)_, err = file.Read(header)if err != nil {fmt.Println("Error reading file:", err)return}fmt.Println("PNG 文件头的16进制信息:")//89504e470d0a1a0a//89504e470d0a1a0afmt.Println(hex.EncodeToString(header))
}

最终验证发现,客户的PNG图片与我本地PNG图片一致,文件头都是符合PNG格式的。

2.2 Alpha图像通道问题(shooting)

接着想着客户图像是灰白色的,而我之前验证的本地图片为彩色,加上我自己gocv处理图片的参数选择的是gocv.IMReadUnchanged。点进去查看源码,发现还有其他的参数,于是尝试替换其他参数。

//我之前代码的用法
mat, err := gocv.IMDecode(imageBuf, gocv.IMReadUnchanged)
// IMReadUnchanged return the loaded image as is (with alpha channel,
//otherwise it gets cropped).
IMReadUnchanged IMReadFlag = -1 # 处理带有Alpha参数的图像
// IMReadColor always converts image to the 3 channel BGR color image.
IMReadColor IMReadFlag = 1 # 将图片转换为BGR三色通道
// IMReadAnyColor the image is read in any possible color format.
IMReadAnyColor IMReadFlag = 4 # 根据图像自动识别任何可能的格式
...

知道这个参数之后,我将gocv.IMDecode(imageBuf, gocv.IMReadUnchanged)中的IMReadUnchanged改为IMReadAnyColor,最后验证,成功处理客户图片。

目前可以知道,我的图像处理参数选择有问题。于是开始查这几种参数有什么区别。其实点进去看源码就可以知道这几种参数的区别。

这个时候如果对图像处理不熟悉的朋友可能会问,Alpha通道是什么意思,其实大家可以简单的理解为和图像的透明度有关。

为了验证这个结论是否正确,我尝试读取客户的PNG和我本地的彩色PNG的颜色Model是否不同:

//color.RGBAModel # 我自己的图像
//color.Gray16Model # 客户的图像

至此,猜想成立,可以知道是我图像的处理颜色的参数选择有误。

3 拓展:图像color.Model

色彩模型(RGB,RGBA,CMYK灰度)
matplotlib中的色彩定义主要用到了RGB、RGBA、CMYK、灰色四种模型。

  • 这里我主要介绍RGBA模型

对这块感兴趣的朋友可以去看这边文章:https://blog.csdn.net/mighty13/article/details/113616772

3.1 color.RGBAModel:三色+Alpha

带有alpha[RGBA 表示传统的32位预处理 Alpha 色,每个颜色都有8位,分别表示红色,绿色,蓝色和阿尔法。 ]

type RGBA struct {R, G, B, A uint8
}

3.2 color.RGBA64Model:64位表示三色+Alpha的值

带有alpha:64位数来表示每个通道的值

type RGBA64 struct {R, G, B, A uint16
}

3.3 color.NRGBAModel:其他颜色不预乘Alpha的值

NRGBA 表示非 Alpha 预乘32位颜色(非 alpha 预乘表示在进行颜色合成时,颜色值不会提前乘以 alpha 通道的值)

  • 预乘:什么是预乘?假设一个像素点,用RGBA四个分量来表示,记做(R,G,B,A),那预乘后的像素就是(RA,GA,B*A, A),这里A的取值范围是[0,1]。所以,预乘就是每个颜色分量都与该像素的alpha分量预先相乘。可以发现,对于一个没有透明度,或者说透明度为1的像素来说,预乘不预乘结果都是一样的。
  • NRGBA代表一个没有32位透明度加乘的颜色。每个红,绿,蓝和透明度都是8bit的数值
type NRGBA struct {R, G, B, A uint8
}

3.4 color.NRGBA64:非预乘Alpha,其他颜色用64位表示

NRGBA64 表示非 alpha 预乘 64 位颜色,每个红色,绿色,蓝色和 alpha 有 16 位

  • NRGBA64代表无透明度加乘的64-bit的颜色,它的每个红,绿,蓝,和透明度都是个16bit的数值。
type NRGBA struct {R, G, B, A uint16
}

3.5 color.AlphaModel:代表一个8-bit的透明度

type Alpha struct {A uint8
}

3.6 color.Alpha16Model:代表一个16位的透明度

type Alpha struct {A uint16
}

3.7 color.GrayModel:灰度通道,黑白图像

只有一个灰度通道,通常用于表示黑白图像【当你需要读取只带有灰度通道的图像时,你应该使用该标志来读取图像。】【也是由RGB组成,不过由于是单通道,因此呈现灰度】

3.8 color.Gray16Model:16位整数表示灰度通道值

16位整数表示灰度通道的值,通常用于表示黑白

参考:

  • https://blog.csdn.net/zxcasd11/article/details/109446056
  • https://blog.csdn.net/u013943420/article/details/76855416

相关文章:

图片处理OpenCV IMDecode模式说明【生产问题处理】

OpenCV IMDecode模式说明【生产问题处理】 1 前言 今天售后同事反馈说客户使用我们的图片处理,将PNG图片处理为JPG图片之后,变为了白板。 我们图片处理使用的是openCV来进行处理 2 分析 2.1 图片是否损坏:非标准PNG头部 于是,马…...

吹响AI技术应用的号角

毫无疑问,各企业正围绕各种技术展开一场持续不断的角逐,力争率先取得领先且具创新性的技术进步,AI技术也不例外。疫情期间,全球各地企业的员工纷纷转向居家办公。因此,为轻松实现这一转型并建立起远程办公的新常态&…...

C //例10.1 从键盘输入一些字符,逐个把它们送到磁盘上去,直到用户输入一个“#”为止。

C程序设计 (第四版) 谭浩强 例10.1 例10.1 从键盘输入一些字符,逐个把它们送到磁盘上去,直到用户输入一个“#”为止。 IDE工具:VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法:使用指针&…...

ARM预取侧信道(Prefetcher Side Channels)攻击与防御

目录 一、预取侧信道简介 1.1 背景:预取分类 二、Arm核会受到影响吗? 2.1 先进的预取器...

数据结构 | 二叉树的各种遍历

数据结构 | 二叉树的各种遍历 文章目录 数据结构 | 二叉树的各种遍历创建节点 && 创建树二叉树的前中后序遍历二叉树节点个数二叉树叶子节点个数二叉树第k层节点个数二叉树查找值为x的节点二叉树求树的高度二叉树的层序遍历判断二叉树是否是完全二叉树 我们本章来实现二…...

Python-赋值运算符(详解)

表示赋值 左侧为变量,右边为值 a b 10#先把10赋值给b,再把b赋值给a 相当于a 10 b 10 链式赋值,但是不推荐,一般一行一个语句,提高可读性,良好的代码风格 多元赋值: a , b 10,20 #python语…...

算法工程师面试八股(搜广推方向)

文章目录 机器学习线性和逻辑回归模型逻辑回归二分类和多分类的损失函数二分类为什么用交叉熵损失而不用MSE损失?偏差与方差Layer Normalization 和 Batch NormalizationSVM数据不均衡特征选择排序模型树模型进行特征工程的原因GBDTLR和GBDTRF和GBDTXGBoost二阶泰勒…...

学习TypeScrip4(数组类型)

数组的类型 1.定义方法:类型[ ] //类型加中括号 let arr:number[] [123] //这样会报错定义了数字类型出现字符串是不允许的 let arr:number[] [1,2,3,1] //操作方法添加也是不允许的 let arr:number[] [1,2,3,] arr.unshift(1)var arr: number[] [1, 2, 3]; /…...

Python文件打包成exe可执行文件

我们平常用python写些脚本可以方便我们的学习办公,但限制就是需要有python环境才能运行。 那能不能直接在没有python环境的电脑上运行我们的脚本呢? 当然可以,那就是直接把python脚本打包成exe可执行程序(注针对win系统&#xf…...

Android : SQLite 增删改查—简单应用

示例图: 学生实体类 Student.java package com.example.mysqlite.dto;public class Student {public Long id;public String name;public String sex;public int age;public String clazz;public String creatDate;//头像public byte[] logoHead;Overridepublic St…...

【蓝桥杯】马的遍历

马的遍历 题目描述 有一个 n m n \times m nm 的棋盘,在某个点 ( x , y ) (x, y) (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。 输入格式 输入只有一行四个整数,分别为 n , m , x , y n, m, x, y n,m,x,y。 …...

导入JSON到xmind

写在前面 这只是一个思路&#xff0c;解决大量树状数据&#xff0c;创建xmind低效问题。 函数可以根据你的实际情况优化 1. 转换json格式 function formatToXimd(atd, str) {if (atd) {for (let index 0; index < atd.length; index) {console.log(str - atd[index].…...

DataGrip 2023.2.3(IDE数据库开发)

DataGrip是一款数据库集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于数据库管理和开发。 DataGrip提供了许多强大的功能&#xff0c;如SQL语句编辑、数据库连接管理、数据导入和导出、数据库比较和同步等等。它支持多种数据库&#xff0c;如MySQL、PostgreSQL、Ora…...

身为 Go 程序员,我为啥更喜欢用 Zig?

Zig 是一种比较新的编程语言&#xff0c;于 2016 年首次推出。Zig 社区将其描述为“一种用于维护稳固的、可优化和可重用软件的通用编程语言”。 看似一句简单的描述&#xff0c;却隐藏着远大的抱负。Zig被看作是可与C语言一较高下的编程语言。此外&#xff0c;Zig 也是一个编…...

Amazon CodeWhisperer 使用体验

文章作者&#xff1a;STRIVE Amazon CodeWhisperer 是最新的代码生成工具&#xff0c;支持多种编程语言&#xff0c;如 java,js,Python 等&#xff0c;能减少开发人员手敲代码时间&#xff0c;提升工作效率。PS:本人是一名 CodeWhisperer 业余爱好者 亚马逊云科技开发者社区为开…...

公众号留言功能怎么申请?

为什么公众号没有留言功能&#xff1f;2018年2月12日&#xff0c;TX新规出台&#xff1a;根据相关规定和平台规则要求&#xff0c;我们暂时调整留言功能开放规则&#xff0c;后续新注册帐号无留言功能。这就意味着2018年2月12日号之后注册的公众号不论个人主体还是组织主体&…...

探索三种生成模型:基于DDPMs、NCSNs和SDEs方法的Diffusion

探索三种生成模型&#xff1a;基于DDPMs、NCSNs和SDEs方法的Diffusion 去噪扩散概率模型&#xff08;DDPMs&#xff09;正向过程反向过程 噪声条件得分网络&#xff08;NCSNs&#xff09;正向过程初始化训练 NCSNs生成样本 反向过程 随机微分方程&#xff08;SDEs&#xff09;原…...

Linux随记(七)

一、欧拉bclinux 21.10安装zabbix-5.0.37.tar.gz &#xff08;zbx-客户端&#xff09; #系统环境&#xff1a; BigCloud Enterprise Linux For Euler 21.10 LTS #软件信息&#xff1a; zabbix-5.0.37.tar.gz &#xff0c; pcre-devel-8.44-2.oe1.x86_64.rpm &#xff0c; inst…...

RESTful API,以及如何使用它构建 web 应用程序。

RESTful API是一种基于REST&#xff08;Representational State Transfer&#xff09;架构风格的API&#xff08;Application Programming Interface&#xff09;&#xff0c;它采用HTTP协议中的GET、POST、PUT、DELETE等方法&#xff0c;对资源进行操作。RESTful API的核心思想…...

【华为OD题库-075】拼接URL-Java

题目 题目描述: 给定一个url前缀和url后缀,通过,分割。需要将其连接为一个完整的url。 如果前缀结尾和后缀开头都没有/&#xff0c;需要自动补上/连接符 如果前缀结尾和后缀开头都为/&#xff0c;需要自动去重 约束:不用考虑前后缀URL不合法情况 输入描述: url前缀(一个长度小于…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...