微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

图像熵整形数组的值错误

如何解决图像熵整形数组的值错误

我有一个代码,用于通过调整图像大小并将其划分为 RGB 通道来查找图像的熵信息。

import os
from PIL import Image
import numpy as np
from scipy.misc import imread
import cv2
import imageio
#读取RGB图像
def openRGB(image_path):
    f =  open(image_path,"rb")
    data = f.read()
    f.close()
    data = [int(x) for x in data]
    data = np.array(data).reshape((256*256,3)).astype(np.uint8)
    return data
def entropy(X):
    n = len(X)
    counts = np.bincount(X)
    probs = counts[np.nonzero(counts)] / n
   en = 0
   for i in range(len(probs)):
       en = en - probs[i] * np.log(probs[i])/np.log(2)
   return en
def getEntropy(image_path):
   data =openRGB(image_path)
   data_B = data[:,0]
   data_G = data[:,1]
   data_R = data[:,2]
   B = entropy(data_B)
   G = entropy(data_G)
   R = entropy(data_R)
   return (R+B+G)/2;

但是,每当我在给定图像上运行 getentropy() 函数时,它都会返回此错误

ValueError: 无法将大小为 37048 的数组重塑为形状 (65536,3)

知道如何重新格式化图像以适合该数组形状吗?

解决方法

有一个简单的解释:image_path 字节长度仅为 37048

使用 np.array(data).reshape((256*256,3)) 时,data 的长度必须为 256*256*3 = 196608 字节。

由于长度不匹配,您收到异常。


重现问题很简单。

  • 创建一个大小为 196608 字节的输入示例文件,也不例外。
  • 创建一个大小为 37048 字节的输入示例文件,得到一个异常。

这是重现问题的代码示例:

import os
#from PIL import Image
import numpy as np
#from scipy.misc import imread
#import cv2
#import imageio

def openRGB(image_path):
    f = open(image_path,"rb")
    data = f.read()
    f.close()
    data = [int(x) for x in data]
    data = np.array(data).reshape((256*256,3)).astype(np.uint8)
    return data

def entropy(X):
    n = len(X)
    counts = np.bincount(X)
    probs = counts[np.nonzero(counts)] / n
    en = 0
    for i in range(len(probs)):
        en = en - probs[i] * np.log(probs[i])/np.log(2)
    return en

def getEntropy(image_path):
    data = openRGB(image_path)
    data_B = data[:,0]
    data_G = data[:,1]
    data_R = data[:,2]
    B = entropy(data_B)
    G = entropy(data_G)
    R = entropy(data_R)
    return (R+B+G)/2


# Create a binary file with random bytes
image_path = 'tmp.bin'

# When n_bytes=196608,there is no exception.
################################################################################
n_bytes = 256*256*3

tmp = np.random.randint(0,255,n_bytes,np.uint8)  # Build random array of n_bytes bytes
with open(image_path,'wb') as f:
    f.write(tmp)  # Write tmp to a binary file

file_size_in_bytes = os.path.getsize(image_path)
print('file_size_in_bytes = ' + str(file_size_in_bytes))

res = getEntropy(image_path)
print(res)
################################################################################


# When n_bytes=37048,an exception is raised: ValueError: cannot reshape array of size 37048 into shape (65536,3)
################################################################################
n_bytes = 37048
tmp = np.random.randint(0,'wb') as f:
    f.write(tmp)  # Write tmp to a binary file

file_size_in_bytes = os.path.getsize(image_path)
print('file_size_in_bytes = ' + str(file_size_in_bytes))

res = getEntropy(image_path)
print(res)
################################################################################

为什么要读取 37048 字节而不是 196608 字节?

image_path 是一个 JPEG 图像文件,您正在使用 f = open(image_path,"rb")data = f.read() 读取图像。

您可以按如下方式阅读和重塑图像:

import cv2

def openRGB(image_path):
    # For example: image_path = 'img.jpg'
    img = cv2.imread(image_path)  # Read image in BGR color format.
    data = np.array(img).reshape(img.shape[0]*img.shape[1],3)  # Reshape to rows x cols x 3 (Blue in data[:,0],green in data[:,1],red in data[:,2]).

    return data

在上面的例子中我使用了img.shape[0]*img.shape[1],图像分辨率是:

height = img.shape[0]
width = img.shape[1]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。