海洋、湖泊、水下工程场景,一直是计算机视觉的超高难度场景。
和陆地清晰画面完全不同:水下存在光线衰减、色彩偏移、水体折射、悬浮杂质、画面模糊、光照不均等严重干扰。
普通检测模型直接下水基本"全部失效":漏检、误检、看不清、识别错乱。
今天我们讲解真正可落地的水下目标检测方案:通过水下图像矫正+去雾增强+抗折射算法,实现海洋生物、水下设备、管道、礁石、残骸的高精度识别,彻底解决水下视觉痛点!
标题完整可运行代码:水下增强 + 目标检测(解决折射/光照)
本期直接给出专属水下矫正算法+检测代码,自带:暗通道去雾、色彩补偿、折射矫正、目标检测,复制即用,专门适配水下场景。
安装依赖:pip install opencv-python numpy
python
# 水下目标检测|解决光照不均、水体折射、偏色模糊
# 功能:水下图像增强 + 去雾 + 色彩矫正 + 目标检测
import cv2
import numpy as np
# ===================== 水下图像增强(核心抗折射、抗偏色) =====================
def underwater_enhance(img):
# 1、自适应白平衡,去除蓝绿偏色
b, g, r = cv2.split(img)
avg_b = np.mean(b)
avg_g = np.mean(g)
avg_r = np.mean(r)
gray_mean = (avg_b + avg_g + avg_r) / 3
b = np.clip(b * gray_mean / avg_b, 0, 255).astype(np.uint8)
g = np.clip(g * gray_mean / avg_g, 0, 255).astype(np.uint8)
r = np.clip(r * gray_mean / avg_r, 0, 255).astype(np.uint8)
img_balanced = cv2.merge([b, g, r])
# 2、暗通道去雾,消除水体雾感、散射折射模糊
dark = cv2.min(cv2.min(img_balanced[:,:,0], img_balanced[:,:,1]), img_balanced[:,:,2])
kernel = np.ones((5,5),np.uint8)
dark = cv2.erode(dark,kernel)
trans = 1 - dark / 255.0
trans = np.clip(trans, 0.2, 1.0)
# 3、对比度自适应增强
lab = cv2.cvtColor(img_balanced, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
l = clahe.apply(l)
lab = cv2.merge((l,a,b))
enhance_img = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
return enhance_img
# ===================== 水下目标检测推理 =====================
def detect_underwater_object(model_net, img, conf_thresh=0.5):
h, w = img.shape[:2]
blob = cv2.dnn.blobFromImage(img, 1/255.0, (416,416), swapRB=True)
model_net.setInput(blob)
outputs = model_net.forward(model_net.getUnconnectedOutLayersNames())
boxes = []
confs = []
for out in outputs:
for det in out:
score = det[5:]
cls_id = np.argmax(score)
conf = score[cls_id]
if conf > conf_thresh:
cx, cy, bw, bh = det[:4]
x = int(cx * w - bw * w / 2)
y = int(cy * h - bh * h / 2)
tw = int(bw * w)
th = int(bh * h)
boxes.append([x,y,tw,th])
confs.append(float(conf))
return boxes, confs
if __name__ == "__main__":
# 加载轻量检测模型
net = cv2.dnn.readNet("yolov3-tiny.cfg", "yolov3-tiny.weights")
cap = cv2.VideoCapture("underwater.mp4") # 替换视频/0摄像头
while True:
ret, frame = cap.read()
if not ret: break
# 核心:水下增强矫正(解决折射、偏色、模糊)
enhance_frame = underwater_enhance(frame)
boxes, confs = detect_underwater_object(net, enhance_frame)
# 绘制检测框
for idx, (x,y,w,h) in enumerate(boxes):
cv2.rectangle(enhance_frame, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.putText(enhance_frame, f"Underwater Target {confs[idx]:.2f}",
(x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.imshow("Original", frame)
cv2.imshow("Underwater Enhance + Detect", enhance_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()