``` import numpy as np import argparse from path import Path from keras.models import Model from keras.layers import Dense, Dropout from keras.applications.inception_resnet_v2 import InceptionResNetV2 from keras.applications.inception_resnet_v2 import preprocess_input # from keras.preprocessing.image import load_img, img_to_array from keras.utils import load_img,img_to_array import tensorflow as tf from utils.score_utils import mean_score, std_score parser = argparse.ArgumentParser(description='Evaluate NIMA(Inception ResNet v2)') parser.add_argument('-dir', type=str, default='D:\python分析\视觉分析/neural-image-assessment-master\images/total1' '', help='Pass a directory to evaluate the images in it') parser.add_argument('-img', type=str, default=['None'], nargs='+', help='Pass one or more image paths to evaluate them') parser.add_argument('-resize', type=str, default='false', help='Resize images to 224x224 before scoring') parser.add_argument('-rank', type=str, default='true', help='Whether to tank the images after they have been scored') args = parser.parse_args() resize_image = args.resize.lower() in ("true", "yes", "t", "1") target_size = (224, 224) if resize_image else None rank_images = args.rank.lower() in ("true", "yes", "t", "1") # give priority to directory if args.dir is not None: print("Loading images from directory : ", args.dir) imgs = Path(args.dir).files('*.png') imgs += Path(args.dir).files('*.jpg') imgs += Path(args.dir).files('*.jpeg') elif args.img[0] is not None: print("Loading images from path(s) : ", args.img) imgs = args.img else: raise RuntimeError('Either -dir or -img arguments must be passed as argument') with tf.device('/CPU:0'): base_model = InceptionResNetV2(input_shape=(None, None, 3), include_top=False, pooling='avg', weights=None) x = Dropout(0.75)(base_model.output) x = Dense(10, activation='softmax')(x) model = Model(base_model.input, x) model.load_weights('weights/inception_resnet_weights.h5') score_list = [] for img_path in imgs: img = load_img(img_path, target_size=target_size) x = img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) scores = model.predict(x, batch_size=1, verbose=0)[0] mean = mean_score(scores) std = std_score(scores) file_name = Path(img_path).name.lower() score_list.append((file_name, mean)) print("Evaluating : ", img_path) print("NIMA Score : %0.3f +- (%0.3f)" % (mean, std)) print() if rank_images: print("*" * 40, "Ranking Images", "*" * 40) score_list = sorted(score_list, key=lambda x: x[1], reverse=True) for i, (name, score) in enumerate(score_list): print("%d)" % (i + 1), "%s : Score = %0.5f" % (name, score))```如果我要分别测量图片的美学评分和技术评分应该怎么做
时间: 2025-07-06 08:31:51 浏览: 11
<think>嗯,用户提供的代码是一个用Keras实现的NIMA(Neural Image Assessment)模型,用来评估图像质量。用户现在想分别测量图片的美学评分和技术评分,我需要分析如何修改或扩展现有代码来实现这一点。
首先,我得回忆一下NIMA模型的基本结构。NIMA通常有两种模型:一个用于美学评分(Aesthetic),另一个用于技术评分(Technical)。两者可能在网络结构上类似,但训练的数据集不同。美学评分可能关注构图、色彩等主观因素,而技术评分可能关注噪声、对比度、曝光等技术指标。
看用户的代码,现在加载的是Inception ResNet v2模型,并加载了特定的权重文件(inception_resnet_weights.h5)。这时候需要确认当前模型是用于哪种评分的。通常,预训练的NIMA模型会有两个不同的权重文件,分别对应美学和技术评分。因此,用户可能需要加载两个不同的模型,或者同一个模型结构但加载不同的权重。
接下来,代码中的模型结构是固定的:基础模型是InceptionResNetV2,然后接Dropout和Dense层输出10个节点的概率分布。分数计算方式是mean_score和std_score,即对10个等级的加权平均和标准差。所以,无论是美学还是技术评分,模型结构可能相同,只是权重不同。
因此,用户需要分别加载两个模型,一个用于美学,一个用于技术。例如,可能有两个权重文件:weights/inception_resnet_aesthetic.h5和weights/inception_resnet_technical.h5。然后,对每张图片分别用两个模型进行预测,得到两个分数。
接下来需要考虑代码的修改步骤。目前的代码只加载了一个模型,处理一次预测。要处理两个评分,可能需要:
1. 加载两个模型实例,分别加载对应的权重。
2. 对每个图像,分别用两个模型进行预测,得到美学和技术分数。
3. 输出时分别显示两种分数。
在代码结构上,可能需要将模型加载部分拆分成两个部分,或者在循环中分别调用两个模型。需要注意的是,Keras模型加载多次可能会占用较多内存,需要确认是否可行。
另外,检查当前代码中是否已经正确加载了权重。用户当前的权重路径是'weights/inception_resnet_weights.h5',可能需要确认是否存在对应的美学和技术权重文件,或者是否需要用户自行准备这两个权重文件。
此外,预处理步骤是否一致?比如,preprocess_input是否相同,对于不同的模型是否需要不同的预处理。例如,InceptionResNetV2通常使用相同的预处理,但如果技术评分模型是基于其他架构,可能需要调整。但假设用户使用的是同一模型结构的不同权重,预处理应该相同。
修改后的代码可能的结构:
- 加载美学模型和技术模型,分别加载各自的权重。
- 对于每个图像,分别用两个模型预测,得到两个分数。
- 输出时同时展示美学和技术分数。
可能的代码修改点:
1. 在模型加载部分,创建两个模型实例,分别加载对应的权重文件。
例如:
with tf.device('/CPU:0'):
# 加载美学模型
base_model_aesthetic = InceptionResNetV2(...)
x_aesthetic = Dropout(...)(base_model_aesthetic.output)
...
model_aesthetic.load_weights('aesthetic_weights.h5')
# 加载技术模型
base_model_technical = InceptionResNetV2(...)
x_technical = Dropout(...)(base_model_technical.output)
...
model_technical.load_weights('technical_weights.h5')
然后,在处理每个图像时,分别调用这两个模型的predict方法。
不过,这样可能会占用较多内存,因为需要加载两个模型。但考虑到用户可能是在CPU上运行,且处理单张图像,可能可行。
另外,原来的代码中,模型加载在with tf.device('/CPU:0')块内,可能需要保持这一点,尤其是如果用户没有GPU的情况下。
另一个可能性是,是否可以将两个任务合并到一个模型中?不过通常不太可能,因为美学和技术评分是两个不同的任务,需要不同的训练数据和输出层。
因此,正确的做法应该是分别加载两个模型,并分别进行预测。
用户当前的代码可能只处理了一个评分类型,因此需要修改为同时处理两个评分。
可能的步骤:
- 确认美学和技术模型的权重文件是否存在,并正确路径。
- 修改模型加载部分,加载两个模型。
- 在处理每张图片时,分别运行两个模型的预测,得到两个分数。
- 输出时同时显示两个分数。
此外,用户可能需要确保两个权重文件正确,并且与模型结构兼容。例如,原代码中的模型结构是否与预训练的权重匹配。例如,原代码中的模型在基础模型后添加了Dropout和Dense层,因此需要确保下载的权重文件对应于这样的结构。
另外,可能需要检查utils.score_utils中的mean_score和std_score函数是否正确,是否适用于两种评分,但通常这两个函数只是计算分数的均值和标准差,是通用的。
总结修改步骤:
1. 获取美学和技术评分模型的权重文件,并确保路径正确。
2. 在代码中加载两个模型:model_aesthetic和model_technical。
3. 对于每个图像,分别用两个模型进行预测,得到两个分数。
4. 输出时同时显示美学和技术评分。
现在,我需要将这些步骤转化为具体的代码修改建议,并指出需要注意的地方,例如确保权重文件的存在,避免内存不足等。</think>要分别测量图片的**美学评分**和**技术评分**,需通过以下步骤修改代码:
---
### 一、核心原理
NIMA模型通过**不同训练目标**的权重实现两类评分:
- **美学评分**:基于构图、色彩等主观审美特征
- **技术评分**:基于噪点、曝光等技术质量特征
---
### 二、代码修改步骤
#### 1. 加载双模型
```python
# 加载美学模型
base_model_aes = InceptionResNetV2(input_shape=(None, None, 3), include_top=False, pooling='avg', weights=None)
x_aes = Dropout(0.75)(base_model_aes.output)
x_aes = Dense(10, activation='softmax')(x_aes)
model_aes = Model(base_model_aes.input, x_aes)
model_aes.load_weights('weights/inception_resnet_aesthetic.h5') # 美学权重
# 加载技术模型
base_model_tec = InceptionResNetV2(input_shape=(None, None, 3), include_top=False, pooling='avg', weights=None)
x_tec = Dropout(0.75)(base_model_tec.output)
x_tec = Dense(10, activation='softmax')(x_tec)
model_tec = Model(base_model_tec.input, x_tec)
model_tec.load_weights('weights/inception_resnet_technical.h5') # 技术权重
```
#### 2. 双模型预测
```python
for img_path in imgs:
# ... 图像加载和预处理保持不变 ...
# 美学评分预测
scores_aes = model_aes.predict(x, batch_size=1, verbose=0)[0]
mean_aes = mean_score(scores_aes)
# 技术评分预测
scores_tec = model_tec.predict(x, batch_size=1, verbose=0)[0]
mean_tec = mean_score(scores_tec)
print("NIMA 美学评分 : %0.3f | 技术评分 : %0.3f" % (mean_aes, mean_tec))
```
---
### 三、关键注意事项
1. **权重文件准备**:
- 需下载预训练的`inception_resnet_aesthetic.h5`和`inception_resnet_technical.h5`
- 官方权重:[NIMA GitHub](https://github.com/idealo/image-quality-assessment)
2. **内存优化**:
```python
with tf.device('/CPU:0'): # 若GPU内存不足,强制使用CPU
# 模型加载和预测代码
```
3. **结果排序逻辑**:
- 若需分别按美学和技术评分排序,需维护两个独立的`score_list`
---
### 四、输出示例
```python
Evaluating : image1.jpg
NIMA 美学评分 : 4.812 | 技术评分 : 3.927
Evaluating : image2.jpg
NIMA 美学评分 : 5.634 | 技术评分 : 4.213
```
---
### 五、扩展建议
- **自定义权重**:若需优化效果,可用自己的数据集微调模型
- **批处理加速**:将`model.predict(batch_size=N)`改为批量推理(需统一图像尺寸)
通过以上修改,即可实现对同一图像的**双重质量评估**。
阅读全文
相关推荐



















