- 图像的几何变换
imgobj = cv2.imread('pho.png') #读取图像
cv2.namedWindow("image") #创建窗口并显示的是图像类型
cv2.imshow("image",imgobj)
cv2.waitKey(0) #等待事件触发,参数0表示永久等待
cv2.destroyAllWindows() #释放窗口
# resize
res = cv2.resize(imgobj,None,fx=0.5, fy=0.5, interpolation = cv2.INTER_CUBIC)
cv2.imshow("image",res)
#warpAffine 仿射
rows,cols = res.shape[0:2]
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(res,M,(cols,rows))
cv2.imshow('img',dst)
#getRotationMatrix2D 旋转
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)#长宽减半 逆时针90度 缩放1倍
dst2 = cv2.warpAffine(res,M,(cols,rows))
cv2.imshow('img',dst2)
#flip 翻转
dst3=cv2.flip(res,1)#0延x轴翻转 任意正数延y轴翻转 任意负数延x/y轴同时翻转
cv2.imshow('img',dst3)
#二值化
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
cv2.imshow('img',binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 霍夫变换 圆检测
def circle_detect(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
trans = cv2.GaussianBlur(gray, (9, 9), 0)
ret_1, thresh_1 = cv2.threshold(trans, 40, 255, cv2.THRESH_BINARY)
circles_2 = cv2.HoughCircles(thresh_1, cv2.HOUGH_GRADIENT, 1, 10, param1=1000, param2=20)
local_2 = circles_2[0][0]
x_2 = int(local_2[0])
y_2 = int(local_2[1])
r_2 = int(local_2[2])
img = cv2.circle(img, (x_2, y_2), r_2, (0, 255, 0), 2)
n = 10
img = cv2.rectangle(img, (x_2 - r_2 - n, y_2 - r_2 - n), (x_2 + r_2 + n, y_2 + r_2 + n), (255, 255, 0), 3)
return img
if __name__ == '__main__':
img = cv2.imread('rec_cir.jpg')
# print(img.shape)
circle_detect(img)
# cv2.namedWindow('addImage')
cv2.imshow('img_add', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 轮廓检测 形状检测
需要进一步预处理 获取更好的特征
import cv2 as cv
import numpy as np
class ShapeAnalysis:
def __init__(self):
self.shapes = {'triangle': 0, 'rectangle': 0, 'polygons': 0, 'circles': 0}
def analysis(self, frame):
h, w, ch = frame.shape
result = np.zeros((h, w, ch), dtype=np.uint8)
# 二值化图像
print("start to detect lines...\n")
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
trans = cv.GaussianBlur(gray, (9, 9), 0)
ret_1, thresh_1 = cv.threshold(trans, 40, 255, cv.THRESH_BINARY)
# ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("input image", frame)
contours, hierarchy = cv. findContours (thresh_1, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for cnt in range(len(contours)):
# 提取与绘制轮廓
cv. drawContours (result, contours, cnt, (0, 255, 0), 2)
# 轮廓逼近
epsilon = 0.01 * cv.arcLength(contours[cnt], True)
approx = cv. approxPolyDP (contours[cnt], epsilon, True)
# 分析几何形状
corners = len(approx)
shape_type = ""
if corners == 3:
count = self.shapes['triangle']
count = count+1
self.shapes['triangle'] = count
shape_type = "三角形"
if corners == 4:
count = self.shapes['rectangle']
count = count + 1
self.shapes['rectangle'] = count
shape_type = "矩形"
if corners >= 10:
count = self.shapes['circles']
count = count + 1
self.shapes['circles'] = count
shape_type = "圆形"
if 4 < corners < 10:
count = self.shapes['polygons']
count = count + 1
self.shapes['polygons'] = count
shape_type = "多边形"
# 求解中心位置
mm = cv.moments(contours[cnt])
cx = int(mm['m10'] / mm['m00'])
cy = int(mm['m01'] / mm['m00'])
cv.circle(result, (cx, cy), 3, (0, 0, 255), -1)
# 颜色分析
color = frame[cy][cx]
color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"
# 计算面积与周长
p = cv.arcLength(contours[cnt], True)
area = cv.contourArea(contours[cnt])
print("周长: %.3f, 面积: %.3f 颜色: %s 形状: %s "% (p, area, color_str, shape_type))
cv.imshow("Analysis Result", self.draw_text_info(result))
cv.imwrite("test-result.png", self.draw_text_info(result))
return self.shapes
def draw_text_info(self, image):
c1 = self.shapes['triangle']
c2 = self.shapes['rectangle']
c3 = self.shapes['polygons']
c4 = self.shapes['circles']
cv.putText(image, "triangle: "+str(c1), (10, 20), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
cv.putText(image, "rectangle: " + str(c2), (10, 40), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
cv.putText(image, "polygons: " + str(c3), (10, 60), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
cv.putText(image, "circles: " + str(c4), (10, 80), cv.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
return image
if __name__ == "__main__":
src = cv.imread("rec_cir.jpg")
ld = ShapeAnalysis()
ld.analysis(src)
cv.waitKey(0)
cv.destroyAllWindows()
- 图像分割
#去噪求梯度
gray = cv2.cvtColor(img_cv2, cv2.COLOR_BGR2GRAY)
trans = cv2.GaussianBlur(gray, (9, 9), 0)
gradX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0)
gradY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
#去噪 二值化
blurred = cv2.GaussianBlur(gradient, (9, 9), 0)
(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY)
#形态 腐蚀膨胀
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
ret_1, binary = cv2.threshold(thresh, 90, 255, cv2.THRESH_BINARY)
# ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
contours, hierarchy= cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = sorted(contours, key=cv2.contourArea, reverse=True)[0]
# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))
# draw a bounding box arounded the detected barcode and display the image
# draw_img = cv2.drawContours(img_cv2, [box], -1, (0, 0, 255), 3)
# cv2.imshow("draw_img", draw_img)
cv2.drawContours(img_cv2, [box], -1, (0, 0, 255), 3)
for cnt in range(len(contours)):
# 提取与绘制轮廓
cv2.drawContours(img_cv2, contours, cnt, (0, 255, 0), 3)
但目标提取效果很好,当图片出现多目标分割且背景复杂或有噪声情况下,无法准确分割出目标图像
- createBackgroundSubtractorMOG2背景去除
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = False)
# fgbg = cv2.createBackgroundSubtractorKNN()
while(cap.isOpened()):
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
cv2.imshow('frame',fgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()