OpenCV Python 常见图像预处理与图像数据增强总结

索引:


图像预处理

1. 滤波

blur = cv2.blur(img, (5,5))        
gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0)        
median_blur = cv2.medianBlur(img, 5)        
bi_blur = cv2.bilateralFilter(img, 9, 75, 75) # src, diameter, sigmaColor, sigmaSpace

2. 二值化

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)        # 大津法
dst = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 2)        # 自适应

3. 通道合并与分离

b, g, r = cv2.split(img)
r  =  r // 2
img = cv2.merge((b, g, r))

4. 图形绘制&添加文字

cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 3)            # pt1, pt2, color, thickness
cv2.rectangle(img, (384, 0), (511, 511), (255, 0, 0), 3)     # pt1, pt2, color, thickness
cv2.circle(img, (447, 63), 63, (0, 0, 255), -1)              # center, radius, color, shift

pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32).reshape((-1, 2))
cv2.polylines(img, [pts], True, (0, 255, 255))               # pts, is_closed, color

font = cv2.FONT_HERSHEY_SIMPLEX        # text, start_pt, font, fontscale, color, thickness, linetype
cv2.putText(img, 'hello', (10, 500), font, 4, (255, 255, 0), 2, cv2.LINE_AA)

5. 图形变换

# 仿射变换 Affine Transformation
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])  # src 的四个顶点
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])  # dst 的四个顶点
M = cv2.getRotationMatrix2D(pts1, pts2)
dst = cv2.warpAffine(img, M, (c, r))

# 透视变换 Perspective Transformation
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (800, 800)) # (s1, s2): scale of the output

# 旋转
angle = random.uniform(-5, 5)
h, w = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, scale=1)
rotated = cv2.warpAffine(img, M, (w, h))

6. 形态学

# kernel ==> element 算子
element = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
element2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
element3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))

# 腐蚀、膨胀
erosion = cv2.erode(img, kernel, iterations=1)
dilation = cv2.dialte(img, kernel)

# 通用形态学操作
kernel = np.ones((5, 5), np.uint8)
dst = cv2.morphologyEx(src, cv2.MORPH_operation, kernel, iteration)

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, 2)

# 形态学梯度 = dilation - erosion,用于提取物体轮廓
gradiet = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

# 顶帽 = src - open,用来分离比邻近点亮一些的斑块
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

# 黑帽 = src - close,用来分离比邻近点暗一些的斑块
blackhat= cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

7. 视频&摄像头

# 打开摄像头
cap = cv2.VideoCapture(0)  # 电脑的第一个摄像头
while True:
	ret, frame = cap.read() # frame即为摄像头读取的帧
	cv2.imshow('frame', frame)
	if cv2.waitKey(30) == 27:
		break
cap.release()     # 释放cap对象
cv2.destroyAllWindows()

# 打开视频文件
cap = cv2.VideoCapture('1.avi') # 打开本地 1.avi 的视频文件
while cap.isOpened():
	ret, frame = cap.read()
	cv2.imshow('frame', frame)
	if cv2.waitKey(30) == 27:
		break
cap.release()
cv2.destroyAllWindows()

# 保存摄像机拍摄的视频文件
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 定义四位的编码解码器(four codec)
# 定义输出,参数列表:filename, codec, frame_rate, (width, height)
output = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
	ret, frame = cap.read()
	if ret==True:
		output.write(frame)
		cv2.imshow('frame', frame)
		if cv2.waitKey(20) == 27:
			break
	else:
		break
cap.release()
cv2.destroyAllWindows()

# 将连续帧(图像)转化为视频
name_list = glob.glob('./frames/*.bmp')
img = cv2.imread(name_list[0])
h, w = img.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'XVID')
output = cv2.VideoWriter('raw.avi', fourcc, 20.0, (w, h))
for name in name_list:
	frame = cv2.imread(name)
	output.write(frame)
output.release()

8. 边缘检测

# laplacian算子,cv2.CV_64F为图像格式,常见的还有cv2.CV_8U
laplacian = cv2.Laplacian(img, cv2.CV_64F)

# sobel算子 cv2.CV_16S: 16位有符号的数据类型
x = cv2.Sobel(img, cv2.CV_16S, 1, 0)    # img, type, dx, dy
y = cv2.Sobel(img, cv2.CV_16S, 0, 1)

# Canny边缘检测:效果最好,提取精细边缘
edges = cv2.Canny(img, 100, 200)  # params: src, thresh1, thresh2

9. 闭包矩形

# 查找轮廓 params: img, mode, method
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓 params: img, contours, contourIdx(-1 means all), thickness, lineType
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)

contour = contours[0]
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)        # contour, closed

# 闭包矩形绘制(无旋转)
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  # visulize

# 最小闭包矩形绘制,params: img, contours, contourIdx, color, thickness
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)

10.直方图均衡化

eq = cv2.equalizeHist(img)    # 单通道

img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)    # 三通道
h, s, v = cv2.split(img)
eq = cv2.equalizeHist(v)
dst = cv2.merge((h, s, eq))

11. 霍夫直线检测

# 霍夫概率直线检测(速度快)
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10)
for line in lines:
	x1, y1, x2, y2 = line[0]
	cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)

12. 存储路径含中文

cv2.imencode(".jpg", img)[1].tofile(img_path)

13. 图像加权合成

dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0.0)    # img1 和 img2 权重分别为 0.7 和 0.3

14. 图像压缩

cv2.imwrite(img_name, img, [int(cv2.IMWRITE_JPEG_QUALITY), 80]

图像增强

import cv2
import numpy as np
import random


class Augment():
    def __init__(self):
        self.inv_prob = 0.5
        self.blur_prob = 0.3
        self.sq_blur_prob = 0.3
        self.bright_prob = 0.5
        self.rotate_prob = 1.
        self.zoom_prob = 1.
        self.gray_prob = 0.0

    def invert(self, image):    # 色彩反转
        return 255 - image

    def blur(self, image):      # 均值滤波模糊
        return cv2.blur(image, (3, 3))

    def sq_blur(self, image):   # 区域插值模糊,模拟图像低分辨率
        image = cv2.resize(image, (400, 128), interpolation=cv2.INTER_AREA)
        return image

    def random_brightness(self, image):     # 明度变化
        c = random.uniform(0.2, 1.8)
        blank = np.zeros(image.shape, image.dtype)
        dst = cv2.addWeighted(image, c, blank, 1 - c, 0)
        return dst

    def rotate(self, image, scale=1.0):     # 旋转
        angle = random.uniform(-5, 5)
        h, w = image.shape[:2]
        center = (w // 2, h // 2)
        M = cv2.getRotationMatrix2D(center, angle, scale)
        rotated = cv2.warpAffine(image, M, (w, h))
        return rotated

    def zoom(self, image, scale=0.3):       # 缩放(根据个人需要)
        h, w = image.shape[:2]
        w_ = int(w * 128 / h)
        if w_ > 400:
            return image
        else:
            w_ = random.randint(max(1, int(w_ * (1 - scale))), w_)
            image = cv2.resize(image, (w_, 128))
            return image

    def gray_scale(self, image):            # 灰度化
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        dst = cv2.merge((gray, gray, gray))
        return dst

    def apply(self, image):
        inv_prob = random.random()
        blur_prob = random.random()
        sq_blur_prob = random.random()
        bright_prob = random.random()
        rotate_prob = random.random()
        zoom_prob = random.random()

        if inv_prob < self.inv_prob:
            image = self.invert(image)

        if bright_prob < self.bright_prob:
            image = self.random_brightness(image)

        if rotate_prob < self.rotate_prob:
            image = self.rotate(image)

        if zoom_prob < self.zoom_prob:
            image = self.zoom(image)

        if blur_prob < self.blur_prob:
            image = self.blur(image)

        if sq_blur_prob < self.sq_blur_prob:
            image = self.sq_blur(image)

        return image

 

  • 18
    点赞
  • 213
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值