Compare commits
3 Commits
69482e6a3f
...
89d8f4c0df
Author | SHA1 | Date | |
---|---|---|---|
89d8f4c0df | |||
d1ed958db5 | |||
abd033b831 |
@ -1,3 +1,8 @@
|
||||
# Graduation-Project
|
||||
|
||||
毕业设计:基于YOLO和图像融合技术的无人机检测系统及安全性研究
|
||||
毕业设计:基于YOLO和图像融合技术的无人机检测系统及安全性研究
|
||||
|
||||
Linux 运行训练
|
||||
```bash
|
||||
nohup python -u yolov8_fed.py >> runtime.log 2>&1 &
|
||||
```
|
@ -8,12 +8,41 @@ import cv2
|
||||
import numpy as np
|
||||
|
||||
from ultralytics import YOLO
|
||||
from skimage.metrics import structural_similarity as ssim
|
||||
|
||||
# 添加YOLOv8模型初始化
|
||||
yolo_model = YOLO("yolov8n.pt") # 可替换为yolov8s/m/l等
|
||||
yolo_model.to('cuda') # 启用GPU加速
|
||||
|
||||
|
||||
def calculate_en(img):
|
||||
"""计算信息熵(处理灰度图)"""
|
||||
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
|
||||
hist = hist / hist.sum()
|
||||
return -np.sum(hist * np.log2(hist + 1e-10))
|
||||
|
||||
|
||||
def calculate_sf(img):
|
||||
"""计算空间频率(处理灰度图)"""
|
||||
rf = np.sqrt(np.mean(np.square(np.diff(img, axis=0))))
|
||||
cf = np.sqrt(np.mean(np.square(np.diff(img, axis=1))))
|
||||
return np.sqrt(rf ** 2 + cf ** 2)
|
||||
|
||||
|
||||
def calculate_mi(img1, img2):
|
||||
"""计算互信息(处理灰度图)"""
|
||||
hist_2d = np.histogram2d(img1.ravel(), img2.ravel(), 256)[0]
|
||||
pxy = hist_2d / hist_2d.sum()
|
||||
px = np.sum(pxy, axis=1)
|
||||
py = np.sum(pxy, axis=0)
|
||||
return np.sum(pxy * np.log2(pxy / (px[:, None] * py[None, :] + 1e-10) + 1e-10))
|
||||
|
||||
|
||||
def calculate_ssim(img1, img2):
|
||||
"""计算SSIM(处理灰度图)"""
|
||||
return ssim(img1, img2, data_range=255)
|
||||
|
||||
|
||||
# 裁剪线性RGB对比度拉伸:(去掉2%百分位以下的数,去掉98%百分位以上的数,上下百分位数一般相同,并设置输出上下限)
|
||||
def truncated_linear_stretch(image, truncated_value=2, maxout=255, min_out=0):
|
||||
"""
|
||||
@ -145,20 +174,42 @@ def main(matchimg_vi, matchimg_in):
|
||||
orimg_vi = matchimg_vi
|
||||
orimg_in = matchimg_in
|
||||
h, w = orimg_vi.shape[:2] # 480 640
|
||||
flag, H, dot = Images_matching(matchimg_vi, matchimg_in) # (3, 3)//获取对应的配准坐标点
|
||||
# (3, 3)//获取对应的配准坐标点
|
||||
flag, H, dot = Images_matching(matchimg_vi, matchimg_in)
|
||||
if flag == 0:
|
||||
return 0, None, 0
|
||||
else:
|
||||
# 配准处理
|
||||
matched_ni = cv2.warpPerspective(orimg_in, H, (w, h))
|
||||
matched_ni, left, right, top, bottom = removeBlackBorder(matched_ni)
|
||||
|
||||
# 裁剪可见光图像
|
||||
cropped_vi = orimg_vi[left:right, top:bottom]
|
||||
|
||||
# fusion = fusions(orimg_vi[left:right, top:bottom], matched_ni)
|
||||
fusion = fusions(orimg_vi, matched_ni)
|
||||
fusion = fusions(cropped_vi, matched_ni)
|
||||
|
||||
# 转换为灰度计算指标
|
||||
fusion_gray = cv2.cvtColor(fusion, cv2.COLOR_RGB2GRAY)
|
||||
cropped_vi_gray = cv2.cvtColor(cropped_vi, cv2.COLOR_BGR2GRAY)
|
||||
matched_ni_gray = matched_ni # 红外图已经是灰度
|
||||
|
||||
# 计算指标
|
||||
en = calculate_en(fusion_gray)
|
||||
sf = calculate_sf(fusion_gray)
|
||||
mi_visible = calculate_mi(fusion_gray, cropped_vi_gray)
|
||||
mi_infrared = calculate_mi(fusion_gray, matched_ni_gray)
|
||||
mi_total = mi_visible + mi_infrared
|
||||
ssim_visible = calculate_ssim(fusion_gray, cropped_vi_gray)
|
||||
ssim_infrared = calculate_ssim(fusion_gray, matched_ni_gray)
|
||||
ssim_avg = (ssim_visible + ssim_infrared) / 2
|
||||
|
||||
# YOLOv8目标检测
|
||||
results = yolo_model(fusion) # 输入融合后的图像
|
||||
annotated_image = results[0].plot() # 绘制检测框
|
||||
|
||||
return 1, annotated_image, dot # 返回带检测结果的图像
|
||||
# 返回带检测结果的图像
|
||||
return 1, annotated_image, dot, en, sf, mi_total, ssim_avg
|
||||
except Exception as e:
|
||||
print(f"Error in fusion/detection: {e}")
|
||||
return 0, None, 0
|
||||
@ -272,9 +323,16 @@ if __name__ == '__main__':
|
||||
img_inf_gray = cv2.cvtColor(img_infrared, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
# 执行融合与检测
|
||||
flag, fusion_result, _ = main(img_visible, img_inf_gray)
|
||||
flag, fusion_result, dot, en, sf, mi, ssim_val = main(img_visible, img_inf_gray)
|
||||
|
||||
if flag == 1:
|
||||
# 展示评价指标
|
||||
print("\n======== 融合质量评价 ========")
|
||||
print(f"信息熵(EN): {en:.2f}")
|
||||
print(f"空间频率(SF): {sf:.2f}")
|
||||
print(f"互信息(MI): {mi:.2f}")
|
||||
print(f"结构相似性(SSIM): {ssim_val:.4f}")
|
||||
|
||||
# 显示并保存结果
|
||||
cv2.imshow("Fusion with Detection", fusion_result)
|
||||
cv2.imwrite("output/fusion_result.jpg", fusion_result)
|
||||
|
@ -1,74 +0,0 @@
|
||||
import numpy as np
|
||||
import cv2
|
||||
from skimage.metrics import structural_similarity as ssim
|
||||
from skimage.filters import sobel
|
||||
from sklearn.metrics import mutual_info_score
|
||||
|
||||
|
||||
# Helper to compute mutual information between two grayscale images
|
||||
def evaluate_mutual_information(img1_gray, img2_gray):
|
||||
hist_2d, _, _ = np.histogram2d(img1_gray.ravel(), img2_gray.ravel(), bins=256)
|
||||
pxy = hist_2d / float(np.sum(hist_2d))
|
||||
px = np.sum(pxy, axis=1)
|
||||
py = np.sum(pxy, axis=0)
|
||||
px_py = np.outer(px, py)
|
||||
nzs = pxy > 0
|
||||
mi = np.sum(pxy[nzs] * np.log(pxy[nzs] / px_py[nzs]))
|
||||
return mi
|
||||
|
||||
|
||||
# Compute SSIM between two grayscale images
|
||||
def evaluate_registration_ssim(img1_gray, img2_gray):
|
||||
return ssim(img1_gray, img2_gray)
|
||||
|
||||
|
||||
# Entropy of grayscale image (fusion quality)
|
||||
def evaluate_fusion_entropy(fusion_img):
|
||||
gray = cv2.cvtColor(fusion_img, cv2.COLOR_RGB2GRAY)
|
||||
hist = cv2.calcHist([gray], [0], None, [256], [0, 256])
|
||||
hist = hist.ravel() / hist.sum()
|
||||
entropy = -np.sum(hist * np.log2(hist + 1e-9))
|
||||
return entropy
|
||||
|
||||
|
||||
# Edge strength using Sobel (fusion quality)
|
||||
def evaluate_fusion_edges(fusion_img):
|
||||
gray = cv2.cvtColor(fusion_img, cv2.COLOR_RGB2GRAY)
|
||||
edges = sobel(gray.astype(float) / 255.0)
|
||||
return np.mean(edges)
|
||||
|
||||
|
||||
# SSIM between fused image and one of the sources
|
||||
def evaluate_fusion_ssim(fusion_img, reference_img):
|
||||
fusion_gray = cv2.cvtColor(fusion_img, cv2.COLOR_RGB2GRAY)
|
||||
ref_gray = cv2.cvtColor(reference_img, cv2.COLOR_RGB2GRAY)
|
||||
return ssim(fusion_gray, ref_gray)
|
||||
|
||||
|
||||
# Return all in one place (stub images would be required to test)
|
||||
def summarize_evaluation(img1_gray, img2_gray, fusion_img, ref_img_for_ssim):
|
||||
return {
|
||||
"Registration SSIM": evaluate_registration_ssim(img1_gray, img2_gray),
|
||||
"Mutual Information": evaluate_mutual_information(img1_gray, img2_gray),
|
||||
"Fusion Entropy": evaluate_fusion_entropy(fusion_img),
|
||||
"Fusion Edge Strength": evaluate_fusion_edges(fusion_img),
|
||||
"Fusion SSIM (vs Ref)": evaluate_fusion_ssim(fusion_img, ref_img_for_ssim),
|
||||
}
|
||||
|
||||
# 将所有评价封装成一个高层函数 evaluate_all
|
||||
def evaluate_all(img1_gray, img2_gray, fusion_img, ref_img_for_ssim, verbose=True):
|
||||
"""
|
||||
评估图像配准和融合质量的通用函数
|
||||
:param img1_gray: 可见光灰度图像(原图)
|
||||
:param img2_gray: 红外灰度图像(配准后)
|
||||
:param fusion_img: 融合图像(RGB)
|
||||
:param ref_img_for_ssim: 可见光RGB图,用于对比SSIM
|
||||
:param verbose: 是否打印结果
|
||||
:return: dict 评价指标结果
|
||||
"""
|
||||
results = summarize_evaluation(img1_gray, img2_gray, fusion_img, ref_img_for_ssim)
|
||||
if verbose:
|
||||
print("图像评价指标如下:")
|
||||
for k, v in results.items():
|
||||
print(f"{k}: {v:.4f}")
|
||||
return results
|
@ -1,26 +0,0 @@
|
||||
from evaluate import *
|
||||
|
||||
# 创建模拟图像数据用于测试
|
||||
# img1_gray:原始灰度图像(可见光)
|
||||
# img2_gray:变换后的灰度图像(红外模拟)
|
||||
# fusion_img:融合图像(可见光 + 红外)
|
||||
# ref_img_for_ssim:参考图像(可见光RGB)
|
||||
|
||||
# 创建基础灰度图像(梯度)
|
||||
img1_gray = np.tile(np.linspace(50, 200, 256).astype(np.uint8), (256, 1))
|
||||
|
||||
# 模拟配准后的图像:加一点噪声和平移
|
||||
img2_gray = np.roll(img1_gray, shift=5, axis=1) # 平移模拟配准偏差
|
||||
noise = np.random.normal(0, 5, img2_gray.shape).astype(np.uint8)
|
||||
img2_gray = cv2.add(img2_gray, noise)
|
||||
|
||||
# 创建 RGB 可见光图(重复三个通道)
|
||||
ref_img_for_ssim = cv2.merge([img1_gray] * 3)
|
||||
|
||||
# 创建融合图像(取两个灰度图平均后合并入RGB)
|
||||
fusion_Y = cv2.addWeighted(img1_gray, 0.5, img2_gray, 0.5, 0)
|
||||
fusion_img = cv2.merge([fusion_Y, img1_gray, img2_gray])
|
||||
|
||||
# 运行评价函数
|
||||
scores = evaluate_all(img1_gray, img2_gray, fusion_img, ref_img_for_ssim)
|
||||
|
Loading…
Reference in New Issue
Block a user