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
)
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 main
import (
"encoding/hex"
"fmt"
func main() {
filePath := "/Users/xsky/GolandProjects/xxx/image-encoder/demo/quality/11.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进制信息:")
fmt.Println(hex.EncodeToString(header))
最终验证发现,客户的PNG图片与我本地PNG图片一致,文件头都是符合PNG格式的。
接着想着客户图像是灰白色的,而我之前验证的本地图片为彩色,加上我自己gocv处理图片的参数选择的是gocv.IMReadUnchanged
。点进去查看源码,发现还有其他的参数,于是尝试替换其他参数。
mat, err := gocv.IMDecode(imageBuf, gocv.IMReadUnchanged)
IMReadUnchanged IMReadFlag = -1 # 处理带有Alpha参数的图像
IMReadColor IMReadFlag = 1 # 将图片转换为BGR三色通道
IMReadAnyColor IMReadFlag = 4 # 根据图像自动识别任何可能的格式
知道这个参数之后,我将gocv.IMDecode(imageBuf, gocv.IMReadUnchanged)
中的IMReadUnchanged
改为IMReadAnyColor
,最后验证,成功处理客户图片。
目前可以知道,我的图像处理参数选择有问题。于是开始查这几种参数有什么区别。其实点进去看源码就可以知道这几种参数的区别。
这个时候如果对图像处理不熟悉的朋友可能会问,Alpha通道
是什么意思,其实大家可以简单的理解为和图像的透明度
有关。
为了验证这个结论是否正确,我尝试读取客户的PNG和我本地的彩色PNG的颜色Model是否不同:
至此,猜想成立,可以知道是我图像的处理颜色的参数选择有误。
色彩模型(RGB,RGBA,CMYK灰度)
matplotlib中的色彩定义主要用到了RGB、RGBA、CMYK、灰色四种模型。
对这块感兴趣的朋友可以去看这边文章:https://blog.csdn.net/mighty13/article/details/113616772
带有alpha[RGBA 表示传统的32位预处理 Alpha 色,每个颜色都有8位,分别表示红色,绿色,蓝色和阿尔法。 ]
type RGBA struct {
R, G, B, A uint8
带有alpha:64位数来表示每个通道的值
type RGBA64 struct {
R, G, B, A uint16
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
NRGBA64 表示非 alpha 预乘 64 位颜色,每个红色,绿色,蓝色和 alpha 有 16 位
- NRGBA64代表无透明度加乘的64-bit的颜色,它的每个红,绿,蓝,和透明度都是个16bit的数值。
type NRGBA struct {
R, G, B, A uint16
type Alpha struct {
A uint8
type Alpha struct {
A uint16
只有一个灰度通道,通常用于表示黑白图像【当你需要读取只带有灰度通道的图像时,你应该使用该标志来读取图像。】【也是由RGB组成,不过由于是单通道,因此呈现灰度】
16位整数表示灰度通道的值,通常用于表示黑白
- https://blog.csdn.net/zxcasd11/article/details/109446056
- https://blog.csdn.net/u013943420/article/details/76855416
在很多应用中,经常会直接把图片的二进制数据进行交换,比如说利用
socket 通信传送图片二进制数据,或者直接用内存数据库(例如 Redis)来传递图片二进制数据。
这个时候,当你的应用程序读到内存里的二进制图片数据时,怎么样直接转为 OpenCV
可以使用的图片格式呢,答案是用 cv::imdecode 这个函数:
std::vectorchar> data(lpData, size
cv2.imdecode报错“cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'imdecode'”一招解决。
image_name = '1.jpg'
im = cv.imread(image_name)
img_encode = cv.imencode('.jpg', im)[1]
data_encode = np.array(img_encode)
img = data_encode.tostring()
imdecode :
nparr = np.fromstr
对于路径中含有中文的图像,直接用cv2.imread读取会报错,上次看到有大佬使用cv2.imdecode就可以正常读取,有点好奇,所以今天来记录下二者用法和区别。
最近遇到一个问题,由于刚刚接触opencv,花了很多时间才解决。问题是:
在android中有一些图片需要处理,处于性能和以后移植的考虑,决定将图片处理的部分用C来写,在安卓中通过JNI调用本地C中函数。安卓中将bitmap中的数据放到byte数组中,然后将byte数组传到C函数,C函数将byte数组恢复成Mat对象,以便使用opencv提供的一些函数。
//native 方法
public na
第一节 HighGUI基础
OpenCV将与操作系统,文件系统,摄像机之类的硬件进行交互的一些函数纳入HighGui(high-level graphical user interface)库中,有了HighGui,我们可以方便的打开窗口,显示图像,读出或者写入图像相关的文件。
1、图像读取与保存
OpenCV的imgcodecs模块提供了很多储存格式的图像读取与保存。经常使用的图像读取与保存函数:
1)cv::imread:从指定的图像文件读取图像数据。如果文件不存在或不支持图像格式,则返回空的Mat。
cv2.imdecode()函数从指定的内存缓存中读取数据,并把数据转换(解码)成图像格式;主要用于从网络传输数据中恢复出图像。
cv2.imencode()函数是将图片格式转换(编码)成流数据,赋值到内存缓存中;主要用于图像数据格式的压缩,方便网络传输。
imdecode()使用
从网络读取图像数据并转换成图片格式:
# -*- coding: utf-8 -*-
学习内容颜色空间RGBYUVYCbCrcv2.imread(img_oath, flag)[..., 0]cv2.imencode()cv2.imdecode()np.newaxisPSNR(Peak Signal-to-Noise Ratio) 峰值信噪比SSIM (Structural SIMilarity) 结构相似性
红绿蓝三个通道。但在科学研究一般不采用RGB颜色空间,因为它的细节难以进行数字化的调整。它将色调,亮度,饱和度三个量放在一起表示,很难分开
在 YUV空间中,
https://blog.csdn.net/spadgerz/article/details/103145959
imag(a,b,c)
分别是图片的height,wide , channel(高,宽,通道数)
b = image[:,:,0]#得到蓝色通道
g = image[:,:,1]#得