使用图像分割技术把下面图片中的船只找出来:
具体思路:基于海天线的图像分割,先运用hough直线检测找到图像中的海天线,在海天线以上利用轮廓提取找到船只。
环境:
Python3.9 Opencv4.5.5.64
具体操作 1.获取图片和灰度图定义获取图片的函数:
def get_image(path):
# 获取图片
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return img, gray
调整图片大小:
img_path = r'路径' original, gray = get_image(img_path) height1 = original.shape[0] width1 = original.shape[1] height2 = gray.shape[0] width2 = gray.shape[1] #获取图片高和宽 sizer = 0.2 original_resize = cv2.resize(original, (int(width1*sizer), int(height1*sizer)), interpolation=cv2.INTER_CUBIC) gray_resize = cv2.resize(gray, (int(width2*sizer), int(height2*sizer)), interpolation=cv2.INTER_CUBIC) #调整图片显示的大小
运行结果:
2.海天线检测使用Canny算子和hough检测:
minlineLength = 200
maxlineGap = 70
edges = cv2.Canny(gray_resize, 20, 100)#Canny算子提取轮廓
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 270, minlineLength, maxlineGap, maxLineGap=5)#找到图中的直线
for line in lines:
for x1, y1, x2, y2 in line:
cv2.line(edges, (x1, y1), (x2, y2), (0, 255, 0), 1)#在轮廓图中把直线画出来(注意:画出来的直线在海面上不止一条!)
pass
Canny算子提取出的轮廓(调整参数可以得到不同的轮廓精度):
Hough直线检测后:
3.在海天线上方使用轮廓检测找到船只
定义轮廓检测函数:
def find_ship(edges, line):
region = edges[0:line[0, 1], :]#高度从图片顶端到海天线
contours, hierachy = cv2.findContours(region, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
return contours
ship = find_ship(edges, lines[0])#由Canny轮廓图知lines中检测到的第一条直线是海天线
cv2.drawContours(original_resize, ship, -1, (0, 255, 0), 1)
cv2.imshow('ships', original_resize)#显示分割出来的船只
cv2.waitKey(0)
得到结果:
非学习方法下的图片分割,只能达到一定精度,但可以看出,基本上船只还是被分割出来了。
完整代码import cv2
import numpy as np
def get_image(path):
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return img, gray
def find_ship(edges, line):
region = edges[0:line[0, 1], :]
contours, hierachy = cv2.findContours(region, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
return contours
img_path = r'路径'
original, gray = get_image(img_path)
height1 = original.shape[0]
width1 = original.shape[1]
height2 = gray.shape[0]
width2 = gray.shape[1]
sizer = 0.2
original_resize = cv2.resize(original, (int(width1*sizer), int(height1*sizer)), interpolation=cv2.INTER_CUBIC)
gray_resize = cv2.resize(gray, (int(width2*sizer), int(height2*sizer)), interpolation=cv2.INTER_CUBIC)
minlineLength = 200
maxlineGap = 70
edges = cv2.Canny(gray_resize, 20, 100)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 270, minlineLength, maxlineGap, maxLineGap=5)
for line in lines:
for x1, y1, x2, y2 in line:
cv2.line(edges, (x1, y1), (x2, y2), (0, 255, 0), 1)
pass
ship = find_ship(edges, lines[0])
cv2.drawContours(original_resize, ship, -1, (0, 255, 0), 1)
cv2.imshow('edges', edges)
cv2.imshow('ships', original_resize)
cv2.waitKey(0)
这里是cv新手,欢迎一起交流~



