Python OpenCV学习总结Day 3.1 图像处理(上篇) 颜色处理与二值化,滤波去噪,形态学腐蚀膨胀,边缘检测

前言

按照OpenCV官方doc顺序来进行学习回忆和总结,本次的内容是opencv中的图像处理核心技术(imgproc.hpp),包括

  • 颜色处理与二值化
  • 滤波去噪
  • 形态学操作
  • 边缘检测

Day3.1 OpenCV图像处理核心技术(上篇)

颜色处理与二值化

图像处理常用的颜色空间有RGB、HSV、YCbCr、GRAY等

颜色空间转换

使用cv2.cvtColor(img, type)进行颜色空间的转换,需要注意的是imread默认读取图片为BGR

import cv2
import numpy as np

if __name__ == '__main__':
    img = cv2.imread('starry_night.png')
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imshow('img', img)
    cv2.imshow('img_hsv', img_hsv)
    cv2.imshow('img_gray', img_gray)
    cv2.waitKey(0)

阈值二值化

使用cv2.threshold()进行图像二值化,

需要注意,src必须是单通道图,thresh是阈值,二值化后像素值为{0, maxval},常用的type有
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_OTSU

	# ret, dst = cv2.threshold(src, thresh, maxval, type)
    cv2.threshold(img_gray, 100, 255, cv2.THRESH_BINARY)

此外,还有自适应阈值二值化方法,

	# cv2.adaptiveThreshold(src, maxval, method, type, blocksize, C)
	dst = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 3, 10)

blocksize是分割计算的区域大小,必须是奇数
C表示每个区域计算出阈值后,减去这个常数作为这个区域的最终阈值

颜色阈值筛选

使用cv2.inRange()进行颜色阈值筛选,其中lowerthres和upperthres分别表示长度与图片通道数相同的阈值数组

	# mask = cv2.inRange(img, lowerthres, upperthres)
    mask = cv2.inRange(img_hsv, np.array([100, 40, 40]), np.array([120, 240, 240]))

输入RGB:
在这里插入图片描述
转到HSV空间:
在这里插入图片描述
HSV空间颜色提取:
在这里插入图片描述

滤波去噪

常用的图像滤波方法包括均值滤波,中值滤波,高斯滤波,双边滤波等
均值滤波将中心附近像素累计平均后作为中心值,滤波后图像变模糊
中值滤波取中心附近像素值的中值,适合去除椒盐噪声
高斯滤波采用高斯核进行加权平均,适合去除高斯噪声
双边滤波在滤波时能保持边缘的清晰度

	# 均值滤波cv2.blur(img, Ksize)
    img_blur = cv2.blur(img, (3, 3))
    # 中值滤波cv2.medianBlur(img, Ksize)
    img_median_blur = cv2.medianBlur(img, 3)
    # 高斯滤波cv2.GaussianBlur(img, Ksize, Sigma)
    img_gauss_blur = cv2.GaussianBlur(img, (3, 3), 0)
    # 双边滤波cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
    img_bliteral_blur = cv2.bilateralFilter(img, 9, 20, 45)

形态学操作

在图像处理,如二值化、颜色筛选后,目标图案被截断需要截断时,可以通过形态学操作进行填充和削减

腐蚀膨胀

主要针对二值图像,腐蚀是将图像中黑色区域进一步“吞噬”白色区域,膨胀则是让白色区域“吞噬”黑色区域。

在形态学操作前,首先要获得“吞噬”的模板,即核的形状,可选的形状有
cv2.MORPH_RECT
cv2.MORPH_CROSS
cv2.MORPH_ELLIPSE
也可以通过numpy数组自定义核形状

	# 获得核 cv2.getStructuringElement(type, Ksize)
	kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
	# or 自定义核形状
	kernel_np = np.ones([3, 3], np.uint8)
	# 腐蚀 cv2.erode(img, kernel, iterations=None)
	img_erode = cv2.erode(img, kernel)	
	# 膨胀 cv2.dilate(img, kernel)
	img_dilate = cv2.dilate(img, kernel)

开运算与闭运算

先腐蚀将图像中相连的部分截断,再膨胀的操作是开运算
先膨胀将图像中断开的部分连接,再腐蚀的操作是闭运算

	kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
	# 开运算
	img_open = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
	# 闭运算
	img_close = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)

边缘检测

传统边缘检测算法主要采用一阶微分算子Sobel,Roberts,Prewitt等以及二阶算子Canny,Laplace等

Sobel算子

def edge_Sobel(img):
    # Sobel 算子
    x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
    y = cv2.Sobel(img, cv2.CV_16S, 0, 1)

    # 转 uint8 ,图像融合
    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_sobel = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_sobel

Roberts算子

def edge_Roberts(img):
    # Roberts 算子
    kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
    kernely = np.array([[0, -1], [1, 0]], dtype=int)

    x = cv2.filter2D(img, cv2.CV_16S, kernelx)
    y = cv2.filter2D(img, cv2.CV_16S, kernely)

    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_roberts = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_roberts

Prewitt算子

def edge_Prewitt(img):
    # Prewitt 算子
    kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)
    kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)

    x = cv2.filter2D(img, cv2.CV_16S, kernelx)
    y = cv2.filter2D(img, cv2.CV_16S, kernely)

    # 转 uint8 ,图像融合
    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_prewitt = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_prewitt

Canny算子

def edge_canny(img):
    # Canny
    dst = cv2.Canny(img, 45, 90)
    img_canny = dst
    return img_canny

Laplace算子

def edge_laplace(img):
    # Laplacian
    dst = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
    img_laplace = cv2.convertScaleAbs(dst)
    return img_laplace

边缘检测测试代码

import cv2
import numpy as np


def edge_Roberts(img):
    # Roberts 算子
    kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
    kernely = np.array([[0, -1], [1, 0]], dtype=int)

    x = cv2.filter2D(img, cv2.CV_16S, kernelx)
    y = cv2.filter2D(img, cv2.CV_16S, kernely)

    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_roberts = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_roberts


def edge_Prewitt(img):
    # Prewitt 算子
    kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)
    kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)

    x = cv2.filter2D(img, cv2.CV_16S, kernelx)
    y = cv2.filter2D(img, cv2.CV_16S, kernely)

    # 转 uint8 ,图像融合
    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_prewitt = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_prewitt


def edge_Sobel(img):
    # Sobel 算子
    x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
    y = cv2.Sobel(img, cv2.CV_16S, 0, 1)

    # 转 uint8 ,图像融合
    X = cv2.convertScaleAbs(x)
    Y = cv2.convertScaleAbs(y)
    img_sobel = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
    return img_sobel


def edge_laplace(img):
    # Laplacian
    dst = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
    img_laplace = cv2.convertScaleAbs(dst)
    return img_laplace


def edge_canny(img):
    # Canny
    dst = cv2.Canny(img, 45, 90)
    img_canny = dst
    return img_canny


if __name__ == "__main__":
    img = cv2.imread('distorted.png')
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, img_thres = cv2.threshold(img_gray, 100, 255, cv2.THRESH_BINARY)
    img_thres = img_gray

    img_roberts = edge_Roberts(img_thres)
    img_prewitt = edge_Prewitt(img_thres)
    img_sobel = edge_Sobel(img_thres)
    img_laplace = edge_laplace(img_thres)
    img_canny = edge_canny(img_thres)
    cv2.imshow('img_roberts', img_roberts)
    cv2.imshow('img_prewitt', img_prewitt)
    cv2.imshow('img_sobel', img_sobel)
    cv2.imshow('img_laplace', img_laplace)
    cv2.imshow('img_canny', img_canny)
    cv2.waitKey(0)

输入:
在这里插入图片描述
Roberts:
在这里插入图片描述
Prewitt:
在这里插入图片描述
Sobel:
在这里插入图片描述
Laplace:
在这里插入图片描述
Canny:
在这里插入图片描述

结语

本次总结回顾了OpenCV图像处理中的核心操作,包括颜色处理,滤波去噪,腐蚀膨胀开闭运算,边缘检测算子。下次将继续学习轮廓操作、霍夫变换和直方图操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值