当前位置:   article > 正文

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

二值化处理的是ycbcr的哪个数据

前言

按照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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

阈值二值化

使用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)
  • 1
  • 2

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

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

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]))
  • 1
  • 2

输入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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

形态学操作

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

腐蚀膨胀

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

在形态学操作前,首先要获得“吞噬”的模板,即核的形状,可选的形状有
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

开运算与闭运算

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

	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)
  • 1
  • 2
  • 3
  • 4
  • 5

边缘检测

传统边缘检测算法主要采用一阶微分算子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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Canny算子

def edge_canny(img):
    # Canny
    dst = cv2.Canny(img, 45, 90)
    img_canny = dst
    return img_canny
  • 1
  • 2
  • 3
  • 4
  • 5

Laplace算子

def edge_laplace(img):
    # Laplacian
    dst = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
    img_laplace = cv2.convertScaleAbs(dst)
    return img_laplace
  • 1
  • 2
  • 3
  • 4
  • 5

边缘检测测试代码

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

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

结语

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/86670
推荐阅读
相关标签
  

闽ICP备14008679号