Index d'évaluation d'image (python)

Un enregistrement complet des métriques d'évaluation d'image :

1. Entropie de l'information

L'entropie est une mesure de la quantité d'informations contenues dans une image. Plus l'entropie est élevée, plus elle contient d'informations, ce qui signifie que plus d'informations peuvent être obtenues à partir de l'image traitée, et la valeur d'entropie de l'image est calculée à l'aide de l'entropie de l'information. .

code:

import cv2
import numpy as np
import math

tmp = []
for i in range(256):
    tmp.append(0)
val = 0
k = 0
res = 0
#'img/1-3.jpg'=6.0404 ;  out2.jpg=7.0361 ;result2=7.1585
image = cv2.imread('img/result2.jpg',0)
img = np.array(image)
for i in range(len(img)):
    for j in range(len(img[i])):
        val = img[i][j]
        tmp[val] = float(tmp[val] + 1)
        k = float(k + 1)
for i in range(len(tmp)):
    tmp[i] = float(tmp[i]/ k)
for i in range(len(tmp)):
    if(tmp[i] == 0):
        res = res
    else:
        res = float(res - tmp[i] * (math.log(tmp[i]) / math.log(2.0)))
print (res)

2. Moyenne et écart type

La valeur moyenne représente la luminosité de l'image, et plus l'image est grande, plus elle est lumineuse, mais on ne peut pas simplement dire que plus l'image est lumineuse, mieux c'est, cela dépend de la situation ;

L'écart type est utilisé pour évaluer le contraste de l'image. Plus l'écart type est grand, plus il y a de couches de dégradés clairs et sombres dans l'image, et plus les détails de l'image sont importants et clairs, ce qui est un bon indice d'évaluation.

code:

from PIL import Image,ImageStat
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('img/1-3.jpg')
img = img.astype(np.float32) / 255
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# plt.imshow(img)

cv2.imshow('img',img)
# 通过img.copy()方法,复制img的数据到mean_img
mean_img = img.copy()
# 使用 .mean() 方法可得出 mean_img 的平均值
print(mean_img.mean())
# mean_img -= mean_img.mean() 等效于 mean_img = mean_img - mean_img.mean()
# 减去平均值,得出零平均值矩阵
mean_img -= mean_img.mean()
# 显示图像
# cv2.imshow(mean_img)
cv2.imshow('mean_img',mean_img)

std_img = mean_img.copy()
# 输出 std_img 的标准差
print(std_img.std())

# std_img /= std_img.mean() 等效于 std_img = std_img / std_img.mean()
# 除于标准差,得出单位方差矩阵
std_img /= std_img.std()
# 显示图像
# plt.imshow(std_img)
cv2.imshow('std_img',std_img)

cv2.waitKey(0)
cv2.destroyAllWindows()

3. Rapport signal sur bruit (rapport signal sur bruit de crête)

Rapport signal/bruit de crête PSNR (implémentation du code python + SSIM + MSIM)_color sponge blog-CSDN blog_psnr rapport signal/bruit de crête

code:

import cv2 as cv
import math
import numpy as np


def psnr1(img1, img2):
    # compute mse
    # mse = np.mean((img1-img2)**2)
    mse = np.mean((img1 / 1.0 - img2 / 1.0) ** 2)
    # compute psnr
    if mse < 1e-10:
        return 100
    psnr1 = 20 * math.log10(255 / math.sqrt(mse))
    return psnr1


def psnr2(img1, img2):#第二种法:归一化
    mse = np.mean((img1 / 255.0 - img2 / 255.0) ** 2)
    if mse < 1e-10:
        return 100
    PIXEL_MAX = 1
    psnr2 = 20 * math.log10(PIXEL_MAX / math.sqrt(mse))
    return psnr2


imag1 = cv.imread("./img/22.jpg")
print(imag1.shape)
imag2 = cv.imread("./img/222.jpg")
print(imag2.shape)
#如果大小不同可以强制改变
# imag2 = imag2.reshape(352,352,3)
#print(imag2.shape)
res1 = psnr1(imag1, imag2)
print("res1:", res1)
res2 = psnr2(imag1, imag2)
print("res2:", res2)

#tensorflow框架里有直接关于psnr计算的函数,直接调用就行了:(更推荐)以下代码
'''
#注意:计算PSNR的时候必须满足两张图像的size要完全一样!
#compute PSNR with tensorflow

import tensorflow as tf
 
def read_img(path):
	return tf.image.decode_image(tf.read_file(path))
 
def psnr(tf_img1, tf_img2):
	return tf.image.psnr(tf_img1, tf_img2, max_val=255)
 
def _main():
	t1 = read_img('t1.jpg')
	t2 = read_img('t2.jpg')
	with tf.Session() as sess:
		sess.run(tf.global_variables_initializer())
		y = sess.run(psnr(t1, t2))
		print(y)
 
 
if __name__ == '__main__':
    _main()
'''

4. Pente moyenne

Dégradé moyen (gradient moyen): fait référence à la différence évidente de niveau de gris près de la bordure de l'image ou des deux côtés de la ligne d'ombre, c'est-à-dire que le taux de changement de niveau de gris est important et que le taux de changement peut être utilisé pour indiquer la clarté de l'image . Il reflète le taux de changement du contraste des petits détails de l'image, c'est-à-dire le taux de changement de densité dans la direction multidimensionnelle de l'image, et caractérise la clarté relative de l'image.

Le gradient moyen est la définition de l'image, qui reflète la capacité de l'image à exprimer le contraste des détails.La formule de calcul est

Gradient d'image : G(x,y) = dx i + dy j ;

dx(i,j) = I(i+1,j) - I(i,j);

dy(i,j) = I(i,j+1) - I(i,j);

Parmi eux, I est la valeur du pixel de l'image (par exemple : valeur RVB), et (i, j) est la coordonnée du pixel .

Les dégradés d'image peuvent généralement également utiliser la différence médiane :

dx(i,j) = [I(i+1,j) - I(i-1,j)]/2 ;

dy(i,j) = [I(i,j+1) - I(i,j-1)]/2 ;

Le bord de l'image est généralement réalisé en effectuant des opérations de gradient sur l'image.

Ce qui précède est une simple définition de gradient, mais il existe en réalité des formules de gradient de plus en plus complexes.

Python opencv learning (6) calcul du gradient d'image_Blog du blog de Liu Zixi-blog CSDN_Gradient de calcul d'image

code:

import cv2 as cv

import numpy as np

'''图像梯度(由x,y方向上的偏导数和偏移构成),有一阶导数(sobel算子)和二阶导数(Laplace算子)

用于求解图像边缘,一阶的极大值,二阶的零点

一阶偏导在图像中为一阶差分,再变成算子(即权值)与图像像素值乘积相加,二阶同理
'''

def sobel_demo(image):
    grad_x = cv.Sobel(image, cv.CV_32F, 1, 0)  # 采用Scharr边缘更突出

    grad_y = cv.Sobel(image, cv.CV_32F, 0, 1)

    gradx = cv.convertScaleAbs(grad_x)  # 由于算完的图像有正有负,所以对其取绝对值

    grady = cv.convertScaleAbs(grad_y)

    #计算两个图像的权值和,dst = src1alpha + src2beta + gamma

    gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)

    cv.imshow("gradx", gradx)

    cv.imshow("grady", grady)

    cv.imshow("gradient", gradxy)



def laplace_demo(image): # 二阶导数,边缘更细
    dst = cv.Laplacian(image, cv.CV_32F)

    lpls = cv.convertScaleAbs(dst)

    cv.imshow("laplace_demo", lpls)



def custom_laplace(image):
    #以下算子与上面的Laplace_demo()是一样的,增强采用np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])

    dst = cv.filter2D(image, cv.CV_32F, kernel=kernel)

    lpls = cv.convertScaleAbs(dst)

    cv.imshow("custom_laplace", lpls)



def Scharr(img):

    scharrx = cv.Scharr(img,cv.CV_64F, dx= 1, dy= 0)
    scharrx = cv.convertScaleAbs(scharrx)

    scharry = cv.Scharr(img,cv.CV_64F, dx = 0, dy = 1)
    scharry = cv.convertScaleAbs(scharry)

    result = cv.addWeighted(scharrx, 0.5, scharry, 0.5, 0)

    cv.imshow("scharrx", scharrx)
    cv.imshow("scharry", scharry)
    cv.imshow("result", result)

src = cv.imread("img/result2.jpg")

cv.imshow("original", src)

sobel_demo(src)

laplace_demo(src)

# custom_laplace(src)
Scharr(src)


cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口

cv.destroyAllWindows()  # 关闭所有窗口


 Le gradient moyen n'est qu'une image d'effet, je ne sais pas comment calculer la valeur spécifique, et c'est en cours de recherche.

5. SSIM

L'indice de similarité structurelle (en anglais : structural similarity index, SSIM index) est un indice utilisé pour mesurer la similarité de deux images numériques. La similarité structurelle consiste à mesurer la corrélation des pixels adjacents dans les images numériques, et la corrélation des pixels adjacents dans l'image reflète les informations structurelles des objets dans la scène réelle. Par conséquent, la distorsion structurelle doit être prise en compte lors de la conception d'une mesure de distorsion d'image.

Indice d'évaluation de la similarité des images SSIM/PSNR_Hengyoucheng's blog-CSDN blog_ssim index


import sys
import numpy
from scipy import signal
from scipy import ndimage
import cv2

def fspecial_gauss(size, sigma):
    x, y = numpy.mgrid[-size//2 + 1:size//2 + 1, -size//2 + 1:size//2 + 1]
    g = numpy.exp(-((x**2 + y**2)/(2.0*sigma**2)))
    return g/g.sum()


def ssim(img1, img2, cs_map=False):
    img1 = img1.astype(numpy.float64)
    img2 = img2.astype(numpy.float64)
    size = 11
    sigma = 1.5
    window = fspecial_gauss(size, sigma)
    K1 = 0.01
    K2 = 0.03
    L = 255 #bitdepth of image
    C1 = (K1*L)**2
    C2 = (K2*L)**2
    mu1 = signal.fftconvolve(window, img1, mode='valid')
    mu2 = signal.fftconvolve(window, img2, mode='valid')
    mu1_sq = mu1*mu1
    mu2_sq = mu2*mu2
    mu1_mu2 = mu1*mu2
    sigma1_sq = signal.fftconvolve(window, img1*img1, mode='valid') - mu1_sq
    sigma2_sq = signal.fftconvolve(window, img2*img2, mode='valid') - mu2_sq
    sigma12 = signal.fftconvolve(window, img1*img2, mode='valid') - mu1_mu2
    if cs_map:
        return (((2*mu1_mu2 + C1)*(2*sigma12 + C2))/((mu1_sq + mu2_sq + C1)*
                    (sigma1_sq + sigma2_sq + C2)), 
                (2.0*sigma12 + C2)/(sigma1_sq + sigma2_sq + C2))
    else:
        return ((2*mu1_mu2 + C1)*(2*sigma12 + C2))/((mu1_sq + mu2_sq + C1)*
                    (sigma1_sq + sigma2_sq + C2))

def mssim(img1, img2):
    """
    refer to https://github.com/mubeta06/python/tree/master/signal_processing/sp
    """
    level = 5
    weight = numpy.array([0.0448, 0.2856, 0.3001, 0.2363, 0.1333])
    downsample_filter = numpy.ones((2, 2))/4.0
    im1 = img1.astype(numpy.float64)
    im2 = img2.astype(numpy.float64)
    mssim = numpy.array([])
    mcs = numpy.array([])
    for l in range(level):
        ssim_map, cs_map = ssim(im1, im2, cs_map=True)
        mssim = numpy.append(mssim, ssim_map.mean())
        mcs = numpy.append(mcs, cs_map.mean())
        filtered_im1 = ndimage.filters.convolve(im1, downsample_filter, 
                                                mode='reflect')
        filtered_im2 = ndimage.filters.convolve(im2, downsample_filter, 
                                                mode='reflect')
        im1 = filtered_im1[::2, ::2]
        im2 = filtered_im2[::2, ::2]
    return (numpy.prod(mcs[0:level-1]**weight[0:level-1])*
                    (mssim[level-1]**weight[level-1]))

img = cv2.imread("img/1-3.jpg",0)
print(img.shape)
noise_img = cv2.imread("img/result2.jpg",0)

ssim_val = ssim(img, noise_img)
mssim_val = mssim(img, noise_img)

print(f"ssim_val: {ssim_val.mean()}")
print(f"mssim_val: {mssim_val}")

Guess you like

Origin blog.csdn.net/m0_63172128/article/details/125856799