import cv2
import numpy as np
import os
import glob
def extract_laser_center2(img: np.ndarray, threshold: int = 100) -> np.ndarray:
if img.ndim == 3 and img.shape[2] == 3:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray = img.copy()
rows, cols = gray.shape
center_map = np.zeros_like(gray, dtype=np.uint8)
for col in range(cols):
col_vals = gray[:, col].astype(np.int32)
mask = col_vals > threshold
if np.any(mask):
weights = col_vals[mask]
ys = np.nonzero(mask)[0]
y_center = (weights * ys).sum() / weights.sum()
x = col
y = int(round(y_center))
if 0 <= y < rows:
center_map[y, x] = 255
return center_map
# ------------------- 配置参数 -------------------
input_folder = r"G:\1126_1106\0509\images_20250509_133744"
image_extensions = ['*.jpg', '*.png', '*.bmp']
save_results = False # 如需保存处理图像,设为 True
output_folder = os.path.join(input_folder, "processed_results")
if save_results and not os.path.exists(output_folder):
os.makedirs(output_folder)
# 扫描所有图像文件
image_paths = []
for ext in image_extensions:
image_paths.extend(glob.glob(os.path.join(input_folder, ext)))
print(f"检测到 {len(image_paths)} 张图像进行批量处理...")
for idx, img_path in enumerate(image_paths, 1):
print(f"\n[{idx}/{len(image_paths)}] 正在处理:{os.path.basename(img_path)}")
image = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print(f"⚠️ 无法读取:{img_path}")
continue
# ----- 亮度与对比度调整 -----
contrast = 110 / 100.0
brightness = -13
adjusted = image.astype(np.float32) * contrast + brightness
adjusted = np.clip(adjusted, 0, 255).astype(np.uint8)
# ----- Gamma校正 -----
gamma = 10 / 100.0
invGamma = 1.0 / gamma
table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(256)]).astype("uint8")
adjusted_gamma = cv2.LUT(adjusted, table)
# ----- 中值滤波 -----
filtered = cv2.medianBlur(adjusted_gamma, 11)
# ----- 高斯滤波 -----
blurred = cv2.GaussianBlur(filtered, (5, 7), 0)
# ----- Otsu 二值化 -----
_, otsu_thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# ----- 形态学清理 -----
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
binary_cleaned = cv2.morphologyEx(otsu_thresh, cv2.MORPH_CLOSE, kernel)
binary_cleaned = cv2.morphologyEx(binary_cleaned, cv2.MORPH_OPEN, kernel)
# ----- 连通域分析 + 面积筛选 -----
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_cleaned, connectivity=8)
filtered_components = np.zeros_like(binary_cleaned)
for i in range(1, num_labels):
if stats[i, cv2.CC_STAT_AREA] >= 100:
filtered_components[labels == i] = 255
# ----- 激光中心提取 -----
laser_center = extract_laser_center2(filtered_components, threshold=100)
# ----- 显示结果 -----
cv2.imshow("原图", image)
cv2.imshow("激光中心", laser_center)
cv2.imshow("连通域筛选", filtered_components)
key = cv2.waitKey() # 可以调整延时
# ----- 可选:保存结果 -----
if save_results:
base_name = os.path.splitext(os.path.basename(img_path))[0]
cv2.imwrite(os.path.join(output_folder, f"{base_name}_center.png"), laser_center)
cv2.imwrite(os.path.join(output_folder, f"{base_name}_binary.png"), filtered_components)
cv2.destroyAllWindows()
print("\n✅ 批量处理完成!")
继续针对金属反光进行优化:
import cv2
import numpy as np
import os
import glob
def extract_laser_center2(img: np.ndarray, threshold: int = 100) -> np.ndarray:
if img.ndim == 3 and img.shape[2] == 3:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray = img.copy()
rows, cols = gray.shape
center_map = np.zeros_like(gray, dtype=np.uint8)
for col in range(cols):
col_vals = gray[:, col].astype(np.int32)
mask = col_vals > threshold
if np.any(mask):
weights = col_vals[mask]
ys = np.nonzero(mask)[0]
y_center = (weights * ys).sum() / weights.sum()
x = col
y = int(round(y_center))
if 0 <= y < rows:
center_map[y, x] = 255
return center_map
# ------------------- 配置参数 -------------------
input_folder = r"G:\1126_1106\0509\images_20250509_103731"
image_extensions = ['*.jpg', '*.png', '*.bmp']
save_results = False # 如需保存处理图像,设为 True
output_folder = os.path.join(input_folder, "processed_results")
if save_results and not os.path.exists(output_folder):
os.makedirs(output_folder)
# 扫描所有图像文件
image_paths = []
for ext in image_extensions:
image_paths.extend(glob.glob(os.path.join(input_folder, ext)))
print(f"检测到 {len(image_paths)} 张图像进行批量处理...")
for idx, img_path in enumerate(image_paths, 1):
print(f"\n[{idx}/{len(image_paths)}] 正在处理:{os.path.basename(img_path)}")
image = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print(f"⚠️ 无法读取:{img_path}")
continue
# ----- 亮度与对比度调整 -----
contrast = 110 / 100.0
brightness = -13
adjusted = image.astype(np.float32) * contrast + brightness
adjusted = np.clip(adjusted, 0, 255).astype(np.uint8)
# ----- Gamma校正 -----
gamma = 10 / 100.0
invGamma = 1.0 / gamma
table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(256)]).astype("uint8")
adjusted_gamma = cv2.LUT(adjusted, table)
d=50
sigmaColor=140
sigmaSpace=150
dst = cv2.bilateralFilter(adjusted_gamma, d, sigmaColor, sigmaSpace)
# ----- 中值滤波 -----
filtered = cv2.medianBlur(dst, 5)
# ----- 高斯滤波 -----
#blurred = cv2.GaussianBlur(filtered, (3, 3), 0)
blurred = filtered
# ----- Otsu 二值化 -----
_, otsu_thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# ----- 形态学清理 -----
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
binary_cleaned = cv2.morphologyEx(otsu_thresh, cv2.MORPH_CLOSE, kernel)
binary_cleaned = cv2.morphologyEx(binary_cleaned, cv2.MORPH_OPEN, kernel)
# ----- 连通域分析 + 面积筛选 -----
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_cleaned, connectivity=8)
filtered_components = np.zeros_like(binary_cleaned)
for i in range(1, num_labels):
if stats[i, cv2.CC_STAT_AREA] >= 50:
filtered_components[labels == i] = 255
# ----- 激光中心提取 -----
laser_center = extract_laser_center2(filtered_components, threshold=100)
# ----- 显示结果 -----
cv2.imshow("img", image)
#cv2.imshow("bilateralFilter", dst)
cv2.imshow("laser_center", laser_center)
#cv2.imshow("filtered_components", filtered_components)
key = cv2.waitKey() # 可以调整延时
# ----- 可选:保存结果 -----
if save_results:
base_name = os.path.splitext(os.path.basename(img_path))[0]
cv2.imwrite(os.path.join(output_folder, f"{base_name}_center.png"), laser_center)
cv2.imwrite(os.path.join(output_folder, f"{base_name}_binary.png"), filtered_components)
cv2.destroyAllWindows()
print("\n✅ 批量处理完成!")