面临一个任务就是要图片中的圆形物体切出来,然后做异常点检测(就是看那些圆形物体是异常点),因为异常点检测的方法还在摸索,现在就先把从图片中把圆形物体完整切出的方法写出来。
2.接下来就是代码部分:
import os
import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
img_path = 'D:\\\\ProgramData\\\\007.png'
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow('original_img', img)
# cv2.imshow('gray', gray)
# cv2.waitKey()
#对模糊图像二值化。梯度图像中不大于90的任何像素都设置为0(黑色)。 否则,像素设置为255(白色)
(_, thresh) = cv2.threshold(gray, 53, 255, cv2.THRESH_BINARY_INV)
# cv2.imshow('thresh', thresh)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel,None,(-1,-1),1)
# cv2.imshow('closed', closed)
# cv2.waitKey(0)#无限期等待输入
(_, cnts, _) = cv2.findContours(closed,cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# draw a bounding box arounded the detected barcode and display the image
img_copy = img.copy()
cv2.drawContours(img_copy, cnts, -1, (0, 255, 0), 1)
以上的工作主要就是打开图片,对图片进行灰度处理,阈值处理,查找边缘,最后画出边缘,经过这一步处理后,大致图片大致是这样的
效果一般,具体图片效果要根据调节阈值化参数来达到
centers = []
for i in range(0,len(cnts)):
(rx,ry),radius = cv2.minEnclosingCircle(cnts[i]) ##找出这些曲线点坐标的最小封闭圆的圆心和半径
center = (int(rx),int(ry))
centers.append(center)
radius = int(radius)
cv2.circle(img,center,28,(255,0,0),2)
这一步是根据上面代码中获取到圆形物体的边缘坐标,用圆形曲线去做拟合,得出每个圆的半径和圆心坐标。经过这一步处理之后,效果大概是这样:
最后根据这些圆心坐标和半径把图片中的圆形物体切出来
r = 28
for i in range(0,len(centers)):
# img_test = cv2.circle(img,centers[i],28,(255,0,0),2)
x = centers[i][0]
y = centers[i][1]
rectX = (x - r)
rectY = (y - r)
if(rectX < 0):
rectX = 0
crop_img = img[rectY:(y+r),rectX:(x+r)] #Y在前,X在后,用矩阵来裁剪圆形区域
cv2.imwrite('D:\\\\ProgramData\\\\cut\\\\'+str(x)+'_'+str(y)+'.png',crop_img)