first commit

This commit is contained in:
hatcher committed 2026-07-17 18:55:31 +08:00
1 parent ae53e9eac5
commit 91cbd01126
514 files changed
+55625 -2203

No files matched your search

+294
View File
@@ -0,0 +1,294 @@
import torch
import cv2
import os
import glob
import numpy as np
import onnxruntime as ort
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
import threading
def preview_frame(video_path, frame_number):
"""预览指定帧的图像"""
cap = cv2.VideoCapture(video_path)
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
ret, frame = cap.read()
cap.release()
if ret:
cv2.imwrite(f'frame_{frame_number}.jpg', frame)
print(f"已保存第 {frame_number} 帧的预览图像")
else:
print(f"无法读取第 {frame_number} 帧")
def extract_specific_frames(video_path, frame_numbers):
"""从视频中提取指定帧号的图像"""
cap = cv2.VideoCapture(video_path)
# 获取视频基本信息
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(f"视频信息:\n分辨率: {frame_width}x{frame_height}\n总帧数: {total_frames}")
# 创建画布 - 宽度为单帧宽度乘以要提取的帧数
canvas_width = frame_width * len(frame_numbers)
canvas = np.zeros((frame_height, canvas_width, 3), dtype=np.uint8)
current_frame = 0
canvas_position = 0
# 按顺序处理指定的帧
for target_frame in sorted(frame_numbers):
print(f"正在处理第 {target_frame} 帧...")
# 快进到目标帧
while current_frame < target_frame:
ret = cap.grab() # 使用grab()而不是read()来快速跳过帧
if not ret:
print(f"无法读取到第 {target_frame} 帧")
break
current_frame += 1
# 读取目标帧
ret, frame = cap.retrieve() # 获取当前帧的图像数据
if ret:
# 将帧放入画布
canvas[:, canvas_position:canvas_position+frame_width] = frame
canvas_position += frame_width
# 保存每个提取的帧(可选)
cv2.imwrite(f'frame_{target_frame}.jpg', frame)
else:
print(f"无法读取第 {target_frame} 帧的图像数据")
cap.release()
# 如果canvas_position小于预期的canvas_width,裁剪未使用的部分
if canvas_position < canvas_width:
canvas = canvas[:, :canvas_position]
return canvas
def preview_all_frames(video_path, interval=10):
"""每隔一定间隔预览并保存帧,用于选择合适的帧"""
cap = cv2.VideoCapture(video_path)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
if frame_count % interval == 0:
cv2.imwrite(f'preview_frame_{frame_count}.jpg', frame)
print(f"已保存第 {frame_count} 帧的预览图像")
frame_count += 1
cap.release()
print(f"总共处理了 {frame_count} 帧")
def get_longimage(video_path2,output_path):
video_path = video_path2
# 是否需要预览帧
need_preview = False
if need_preview:
# 预览特定帧
preview_frames = [13, 82, 196, 290, 381]
for frame_num in preview_frames:
preview_frame(video_path, frame_num)
# 或者每隔10帧预览一次
# preview_all_frames(video_path, interval=10)
return
# 指定要提取的帧号
frame_numbers = [13, 82, 196, 290, 381, 483, 697, 798, 893, 1047]
# 提取帧并拼接
panorama = extract_specific_frames(video_path, frame_numbers)
# 保存结果
cv2.imwrite(os.path.join(output_path,'panorama.jpg'), panorama)
print(f"全景图已保存,尺寸: {panorama.shape[1]}x{panorama.shape[0]}")
def init_onnx():
"""Initialize ONNX Runtime session"""
test_weights = "/data1/Hatcher/model/PopulationCounting/Bayesian_project_ours/sim-CAS-base-test.onnx"
if 'CUDAExecutionProvider' in ort.get_available_providers():
print("CUDA is available. Using GPU.")
providers = ["CUDAExecutionProvider"] if ort.get_device() == "GPU" else ["CPUExecutionProvider"]
else:
print("CUDA not available. Using CPU.")
providers = ["CPUExecutionProvider"]
ort_session = ort.InferenceSession(test_weights, providers=providers)
return ort_session
def split_image(image):
"""Split large image into 800x800 patches"""
h, w = image.shape[:2]
# Calculate optimal width for resizing
n_segments = max(1, w // 800)
target_w = n_segments * 800
scale = target_w / w
# Resize image to make width divisible by 800
new_w = target_w
new_h = int(h * scale)
resized_img = cv2.resize(image, (new_w, new_h))
# Split into patches
patches = []
positions = [] # Store original positions for reconstruction
for i in range(0, new_w, 800):
patch = resized_img[:, i:i+800]
if patch.shape[1] < 800: # Handle last patch if smaller than 800
continue
patches.append(patch)
positions.append((i, i+800))
return patches, positions, scale, (new_h, new_w)
def process_patch(patch, ort_session):
"""Process a single 800x800 patch"""
# Preprocess patch
img = cv2.resize(patch, (800, 800))/255.0
img = img[np.newaxis, :, :].transpose(0,3,1,2)
input_blob = np.array(img, dtype=np.float32)
# Run inference
onnx_input_name = ort_session.get_inputs()[0].name
onnx_outputs_names = ort_session.get_outputs()[0].name
onnx_result = ort_session.run([onnx_outputs_names],
input_feed={onnx_input_name: input_blob})
# Get density map
density_map = onnx_result[0][0][0]
density_map[density_map<1e-6] = 0
return density_map
def process_single_image(image_path, save_root, ort_session, file_lock):
"""Process a single large image"""
try:
# Get image name
image_name = os.path.basename(image_path)
result_name = f"result_{image_name}"
# Read image
img_or = cv2.imread(image_path)
if img_or is None:
print(f"Failed to read image: {image_path}")
return False
# Split image into patches
patches, positions, scale, (new_h, new_w) = split_image(img_or)
# Process each patch
density_maps = []
total_count = 0
for patch in patches:
density_map = process_patch(patch, ort_session)
density_maps.append(density_map)
total_count += np.sum(density_map)
# Combine density maps
combined_density = np.zeros((new_h, new_w))
for density_map, (start_x, end_x) in zip(density_maps, positions):
resized_density = cv2.resize(density_map, (800, new_h))
combined_density[:, start_x:end_x] = resized_density
# Resize combined density map back to original size
combined_density = cv2.resize(combined_density, (img_or.shape[1], img_or.shape[0]))
# Create heatmap
heatmap = combined_density/np.max(combined_density)
heatmap = np.power(heatmap, 0.7) # 降低gamma值会使颜色更深
heatmap = np.uint8(heatmap*255)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
# Create visualization
imgheatmap_W = int(img_or.shape[1]/3)
imgheatmap_H = int(img_or.shape[0]/3)
density_result = cv2.resize(heatmap,(imgheatmap_W,imgheatmap_H))
# Add density map to top-left corner
img_or[0:imgheatmap_H, 0:imgheatmap_W] = density_result
# Add count text
cv2.putText(img_or, f"Count: {int(total_count)}", (50,200),
cv2.FONT_HERSHEY_SIMPLEX, 4, (0,0,255), 8)
# Save result
save_path = os.path.join(save_root, result_name)
with file_lock:
cv2.imwrite(save_path, img_or)
print(save_path)
return True
except Exception as e:
print(f"Error processing {image_path}: {str(e)}")
return False
def process_images_batch(input_folder, num_threads=4):
"""Process images in parallel"""
# Initialize ONNX session
ort_session = init_onnx()
# Create output directory
save_root = os.path.join(input_folder, "results")
os.makedirs(save_root, exist_ok=True)
# Get image paths
image_paths = glob.glob(os.path.join(input_folder, "*.jpg")) + \
glob.glob(os.path.join(input_folder, "*.png"))
print(f"Found {len(image_paths)} images to process")
# Initialize counters and locks
success_count = 0
counter_lock = threading.Lock()
file_lock = threading.Lock()
# Create progress bar
pbar = tqdm(total=len(image_paths), desc="Processing images")
def process_with_progress(image_path):
nonlocal success_count
result = process_single_image(image_path, save_root, ort_session, file_lock)
with counter_lock:
if result:
success_count += 1
pbar.update(1)
pbar.set_postfix({'succeeded': success_count})
# Process images in parallel
with ThreadPoolExecutor(max_workers=num_threads) as executor:
executor.map(process_with_progress, image_paths)
pbar.close()
print(f"Processing complete. Successfully processed {success_count} images")
if __name__ == "__main__":
video_path = "/data1/Hatcher/model/project/MPKFNet/mmexport1733810879708.mp4"
out_put_path = "./20251105001"
if not os.path.exists(out_put_path):
os.makedirs(out_put_path)
get_longimage(video_path,out_put_path)
# Start processing
process_images_batch(out_put_path)