为图像指定(255,0,0)像素值后,保存重加载numpy查询返回空数组
问题描述
我给图像的某个像素指定了(255,0,0)的像素强度值,保存图像后重新加载,用numpy查找该像素强度值的位置,得到的是空数组。
我的代码:
import cv2 import numpy as np # 原代码遗漏该导入,实际运行需补充 # 读取图像 img = cv2.imread('abc.jpg') # 赋值像素值 img[779,804] = (255,0,0) # 保存图像 cv2.imwrite('new_img.jpg', img) read_img = cv2.imread('new_img.jpg') intensity_val = np.where((read_img[:,:,0]==255)&(read_img[:,:,1]==0)&(read_img[:,:,2]==0)) print(intensity_val)
输出结果:
(array([], dtype=int64), array([], dtype=int64))
问题原因
- JPEG有损压缩特性:JPEG是有损压缩格式,保存时会对像素值进行压缩优化,哪怕仅修改单个像素,压缩后的实际像素值也可能偏离你设置的
(255,0,0),导致重新读取后无法匹配到完全一致的值。 - 压缩引入细微偏差:OpenCV默认以BGR通道顺序读取图像,你设置的
(255,0,0)对应BGR格式的红色,但JPEG压缩会引入细微的通道值偏差(比如变为(254,1,0)),精准匹配条件下会找不到目标像素。
解决方法
使用无损格式保存
换成PNG这类无损压缩格式,避免像素值被修改:cv2.imwrite('new_img.png', img) read_img = cv2.imread('new_img.png') intensity_val = np.where((read_img[:,:,0]==255)&(read_img[:,:,1]==0)&(read_img[:,:,2]==0))放宽匹配条件
若必须使用JPEG,可通过设置误差阈值查找接近目标值的像素:target = np.array([255, 0, 0], dtype=np.uint8) # 计算每个像素与目标值的欧氏距离 diff = np.sqrt(np.sum((read_img - target)**2, axis=2)) # 筛选距离小于阈值的像素(阈值可根据实际情况调整) intensity_val = np.where(diff < 5)确认通道顺序匹配
若你实际想设置RGB格式的红色,需先转换通道顺序:# 转换为RGB通道顺序 img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_rgb[779,804] = (255,0,0) # RGB格式的红色 cv2.imwrite('new_img.png', img_rgb) # 读取后转回RGB格式再匹配 read_img_rgb = cv2.cvtColor(cv2.imread('new_img.png'), cv2.COLOR_BGR2RGB) intensity_val = np.where((read_img_rgb[:,:,0]==255)&(read_img_rgb[:,:,1]==0)&(read_img_rgb[:,:,2]==0))
内容的提问来源于stack exchange,提问作者keeponlearning101
相关产品推荐
相关产品推荐

