OpenCV 高级部分(下) 掩膜+直方图+阈值+边缘检测

掩膜/遮罩 Masking

  可以通过位运算来实现,来让我们更好地关注图像的某一部分。

import cv2 as cv
import numpy as np

img = cv.imread('Photos/cats.jpg')
cv.imshow('Cats',img)

blank = np.zeros(img.shape[:2],dtype='uint8')
#遮罩的大小(the dimensions of the mask)必须和所作用图像大小一致
cv.imshow('Blank Image',blank)

mask = cv.circle(blank,(img.shape[1]//2,img.shape[0]//2),100,255,-1) #圆形遮罩
#这里的遮罩不是遮起来,而是需要显示的部分
cv.imshow('Mask',mask)

masked = cv.bitwise_and(img,img,mask=mask) #img & img = img
cv.imshow('Masked Image',masked)

cv.waitKey(0)

在这里插入图片描述

直方图计算 Histogram Computation

  可视化像素强度分布。先查看灰度直方图(Grayscale Histogram)。

import cv2 as cv
import matplotlib.pyplot as plt

img = cv.imread('Photos/cats.jpg')
cv.imshow('Cats',img)

gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
cv.imshow('Gray',gray)

#Grayscale Histogram
gray_hist = cv.calcHist([gray],[0],None,[256],[0,256])
#images传递的参数格式为列表,传入图像应该用中括号[]括起来
#channels传入图像的通道,如果是灰度图像那只有一个通道,值为0,用[]传入
#mask是掩膜图像
#histSize是灰度级的个数,需要中括号
#ranges是像素值的范围,通常取[0,256]

plt.figure()
plt.title('Grayscale Histogram')
plt.xlabel('Bins') #x轴标题
plt.ylabel('num of pixels') #y轴标题
plt.plot(gray_hist)
plt.xlim([0,256])
plt.show()

cv.waitKey(0)

  x轴表示像素强度值,y轴表示该像素强度值的像素个数。

  查看颜色直方图(Colour Histogram),顺便在其中再应用一下遮罩。

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np

img = cv.imread('Photos/cats.jpg')
cv.imshow('Cats',img)

blank = np.zeros(img.shape[:2],dtype='uint8')
circle = cv.circle(blank,(img.shape[1]//2,img.shape[0]//2),100,255,-1)
mask = cv.bitwise_and(img,img,mask=circle)
cv.imshow('Mask',mask)

#Colour Histogram
plt.figure()
plt.title('Colour Histogram')
plt.xlabel('Bin')
plt.ylabel('num of pixels')
colors = ('b','g','r')
for i,col in enumerate(colors):
    hist = cv.calcHist([img],[i],circle,[256],[0,256])
    #注意此处的遮罩参数不是mask而是circle
    plt.plot(hist,color=col)
    plt.xlim([0,256])
plt.show()

cv.waitKey(0)

阈值 Thresholding

  选择一个值作为阈值,当图像像素高于这个值时设为某一固定值,否则设为0。这一过程也能被称作二值化。之前轮廓检测时也有通过阈值将图像二值化后获取轮廓。

import cv2 as cv

img = cv.imread('Photos/cats.jpg')
cv.imshow('Cats',img)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
cv.imshow('Gray',gray)

#Simple Thresholding 简单的阈值化
threshold,thresh = cv.threshold(gray,150,255,type=cv.THRESH_BINARY)
#当像素值大于150时,将像素值设置为255(白),否则则设为0(黑)
#thresh为返回的二值化图像,threshold就是设置的阈值150
cv.imshow('Simple Thresholded',thresh)

#逆阈值图像
threshold,thresh_inv = cv.threshold(gray,150,255,type=cv.THRESH_BINARY_INV)
cv.imshow('Simple Thresholded Inverse',thresh_inv)

#Adaptive Thresholding 自适应阈值
adaptive_thresh = cv.adaptiveThreshold(gray,255,adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C,
                                       thresholdType=cv.THRESH_BINARY,blockSize=11,C=3)
#method:选用的方法是计算像素领域的均值作为阈值(使用高斯方法会加权重)
#blockSize:内核大小(用于计算的领域大小)
#C:表示可以给所得均值减去C用来微调我们的阈值
cv.imshow('Adaptive Thresholding',adaptive_thresh)

cv.waitKey(0)

在这里插入图片描述

图像梯度和边缘检测 Gradient and Edge Detection

  之前曾使用过Canny边缘检测器抓取图像的边缘,现在使用Laplacian和Sobel来进行边缘检测和对比。

import cv2 as cv
import numpy as np

img = cv.imread('Photos/park.jpg')
cv.imshow('Park',img)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
cv.imshow('Gray',gray)
#有一些函数要求输入的image是单通道图像

#Laplacian 拉普拉斯算子 本质上是计算该图像的梯度
lap = cv.Laplacian(gray,ddepth=cv.CV_64F)
#ddepth:期望的图像深度
lap = np.uint8(np.absolute(lap))
#uint8是专门用于存储各种图像的(包括RGB,灰度图像等),范围是从0–255
#图像本身不能具有负像素,故使用np.absolute
cv.imshow('Laplacian',lap)

#Sobel 在x方向和y方向上计算梯度
sobelx = cv.Sobel(gray,cv.CV_64F,1,0)
sobely = cv.Sobel(gray,cv.CV_64F,0,1)
combined_sobel = cv.bitwise_or(sobelx,sobely)

cv.imshow('Sobel X',sobelx)
cv.imshow('Sobel Y',sobely)
cv.imshow('Combined Sobel',combined_sobel)

canny = cv.Canny(gray,135,175)
cv.imshow('Canny',canny)
cv.waitKey(0)


  Canny得到的版本看上去最为简洁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值