做SAR图像分类预处理时用到K-means聚类把前景后景分开。由于聚类效果不太理想,总有些错分的像素点和目标区域不闭合的情况,且目标区域的边缘也不够平滑,所以在K-means之后还进行了一些后续操作,包括二值化处理,开运算等操作,再进行目标区域定位画框,效果就好很多。

完整代码和注释如下:
# -*- coding: utf-8 -*- # autho:xier ​​​​​​​ import cv2 import os import math
import numpy as np import PIL.Image as image import matplotlib.pyplot as plt
from sklearn.cluster import KMeans from pylab import mpl
mpl.rcParams['font.sans-serif'] = 'NSimSun, Times New Roman' # 加载图片,转成矩阵 def
load_data(file_path): f = open(file_path, 'rb') # 二进制打开 data = [] img =
image.open(f) # 以列表形式返回图片像素值 m, n = img.size # 图片大小 for i in range(m): for j in
range(n): # 将每个像素点RGB颜色处理到0-1范围内并存放data x = img.getpixel((i, j))
data.append([x/256.0]) f.close() return np.mat(data), m, n # 以矩阵型式返回data,图片大小
def K_means(img_data, row, col): label = KMeans(n_clusters=2, n_init=40,
init='k-means++').fit_predict(img_data) # 聚成两类 label = label.reshape([row,
col]) # 聚类获得每个像素所属的类别 if np.sum(label) >= row * col/2: #分类相反 label =
np.abs(np.ones((row, col)) - label) pic_k = image.new("L", (row, col)) #
创建一张新的灰度图保存聚类后的结果 for i in range(row): # 根据所属类别向图片中添加灰度值 for j in range(col):
pic_k.putpixel((i, j), int(256 / (label[i][j] + 1))) return pic_k #
对K_means聚类分割后的图像进行阈值分割转成二值图像 def Thresh_and_blur(img): (_, thresh) =
cv2.threshold(img, 130, 255, cv2.THRESH_BINARY) return thresh #
用数字形态学先腐蚀掉噪声再进行膨胀(开运算) def image_morphology(thresh): # 建立一个椭圆核函数 kernel =
cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) # 执行图像形态学 opened =
cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) # closed =
cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel) #opened = cv2.erode(opened,
None, iterations=4) # 腐蚀4次 #opened = cv2.dilate(opened, None, iterations=4) #
膨胀4次 return opened def findcnts_and_box_point(opened): #
这里opencv3返回的是三个参数,源图像、轮廓信息、可选参数 # 轮廓检索模式:cv2.RETR_LIST表示提取所有轮廓并记录在列表 #
轮廓逼近方法:cv2.CHAIN_APPROX_SIMPLE,压缩水平、垂直、对角元素,保留终点坐标,如矩形轮廓用4个角点表示 (_, cnts, _) =
cv2.findContours(opened.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) c =
sorted(cnts, key=cv2.contourArea, reverse=True) c = c[1] # compute the rotated
bounding box of the largest contour rect = cv2.minAreaRect(c) #
生成最小外接矩形,retval包含中心坐标、矩形宽高和旋转角度 box = np.int0(cv2.boxPoints(rect)) #
得到旋转矩阵四个顶点坐标 return box def drawcnts_and_cut(original_img, box): # draw a
bounding box arounded the detected barcode and display the image draw_img =
cv2.drawContours(original_img.copy(), [box], -1, (0, 0, 255), 3) # 截取图像 Xs =
[i[0] for i in box] Ys = [i[1] for i in box] x1 = min(Xs) x2 = max(Xs) y1 =
min(Ys) y2 = max(Ys) y_mid = y1 + math.ceil((y2 - y1)/2) x_mid = x1 +
math.ceil((x2 - x1) / 2) crop_img = original_img[y_mid-25:y_mid+25,
x_mid-25:x_mid+25] # 裁成50*50目标图像 return draw_img, crop_img def walk():
original_Folder = '自己存放图片的文件夹' OR_Vector = os.listdir(original_Folder) #
读取待处理文件夹中所有的文件 for k in range(len(OR_Vector)): # 取一个类别文件夹 Class_Folder =
os.path.join('%s\%s' % (original_Folder, OR_Vector[k])) # 读取该类别文件夹的所有图片
CF_Tensor = os.listdir(Class_Folder) for p in range(len(CF_Tensor)): # 取一张图片 #
取一张图片 Image_Path = os.path.join('%s\%s' % (Class_Folder, CF_Tensor[p]))
original_img = cv2.imread(Image_Path) img_data, row, col =
load_data(Image_Path) pic_k = K_means(img_data, row, col) pic_k =
np.asarray(pic_k) thresh = Thresh_and_blur(pic_k) opened =
image_morphology(thresh) box = findcnts_and_box_point(opened) draw_img,
crop_img = drawcnts_and_cut(original_img, box) # 保存切割后的图片 # Save_Folder =
'F:\pycharm\\test_IO\\MSTAR-10_denoise_enl4\\train_denoise_enl4_segment' #
SA_Vector = os.listdir(Save_Folder) # 读取保存的文件夹中所有的文件 # Class_Folder2 =
os.path.join('%s\%s' % (Save_Folder, SA_Vector[k])) # Save_Path =
os.path.join('%s\%s' % (Class_Folder2, CF_Tensor[p])) # cv2.imwrite(Save_Path,
crop_img) titles = [u'去噪后图像', u'K-means聚类后', u'二值化处理', u'开运算', u'定位目标区域',
u'切割后的图像'] images = [original_img, pic_k, thresh, opened, draw_img, crop_img] #
for i in range(6): plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.show()
cv2.waitKey(20180407) walk()
结果展示如下:
图像K-means分割及目标区域切割
 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信