基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图

大四毕业后的这个暑假正式开始学习openCV

参考教程:唐宇迪老师: https://www.bilibili.com/video/BV1tb4y1C7j7

1.图像梯度-Sobel算子

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第1张图片

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

ddepth:图像的深度,通常是-1

dx和dy分别表示水平和竖直方向

ksize: 是Sobel算子的大小

demo1:

import cv2

img = cv2.imread('D:\\openCV files\\data\\1\\pie.png',cv2.IMREAD_GRAYSCALE)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)   #cv2.CV_64F表示结果可以带负数(防止被截断),1,0表示只要水平的,不要竖直的
cv_show(sobelx,'sobelx')

#由于算子是右边减去左边,白减去黑是整数,黑减去白则是负数,所有的负数会被截断为0,所以要取绝对值
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)   #cv2.CV_64F表示结果可以带负数,1,0表示只要水平的,不要竖直的
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)   #cv2.CV_64F表示结果可以带负数,0,1表示只要竖直的
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely')

#分别计算x和y,再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

#不建议直接计算
sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)   #水平竖直都设成1
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')

img = cv2.imread('D:\\openCV files\\data\\1\\lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)   #cv2.CV_64F表示结果可以带负数,1,0表示只要水平的,不要竖直的
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)   #cv2.CV_64F表示结果可以带负数,0,1表示只要竖直的
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

#整体计算结果很模糊!
img = cv2.imread('D:\\openCV files\\data\\1\\lena.jpg',cv2.IMREAD_GRAYSCALE)

sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)   #水平竖直都设成1
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')

out1:
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第2张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第3张图片

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第4张图片

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第5张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第6张图片

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第7张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第8张图片

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第9张图片
2.Scharr算子和laplacian算子

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第10张图片
demo2:

import cv2
import numpy as np

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:\\openCV files\\data\\1\\lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)

#Scharr算子细节更丰富一些
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)

#laplacian算子细节不太丰富,一般不单独使用
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)

res = np.hstack((sobelxy,scharrxy,laplacian)) #注意这里一直是双括号
cv_show(res,'res')

out2:

3.Canny边缘检测

(1)使用高斯滤波器,以平滑图像,滤除噪声。

(2)计算图像中每个像素点的梯度强度和方向。

(3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。

(4)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

(5)通过抑制孤立的弱边缘最终完成边缘检测。

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第11张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第12张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第13张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第14张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第15张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第16张图片
demo3:

import cv2
import numpy as np

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:\\openCV files\\data\\1\\lena.jpg',cv2.IMREAD_GRAYSCALE)

v1 = cv2.Canny(img, 80, 150)  #80:minVal  150:maxVal
v2 = cv2.Canny(img, 50, 100)

res = np.hstack((v1, v2))
cv_show(res, 'res')

img = cv2.imread('D:\\openCV files\\data\\1\\car.png',cv2.IMREAD_GRAYSCALE)

v1 = cv2.Canny(img, 120, 250)  #80:minVal  150:maxVal
v2 = cv2.Canny(img, 50, 100)

res = np.hstack((v1, v2))
cv_show(res, 'res')

out3:
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第17张图片

4.金字塔制作
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第18张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第19张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第20张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第21张图片

demo4:

import cv2
import numpy as np

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:\\openCV files\\data\\1\\AM.png')
cv_show(img,'img')
print(img.shape)


#高斯金字塔
#向上采样
up = cv2.pyrUp(img)
cv_show(up,'up')
print(up.shape)

#向下采样
down = cv2.pyrDown(img)
cv_show(down,'down')
print(down.shape)

#继续向上采样
up2 = cv2.pyrUp(up)
cv_show(up2,'up2')
print(up2.shape)

#先向上采样,再向下
up = cv2.pyrUp(img)
up_down = cv2.pyrDown(up)  #并没有恢复原图
cv_show(np.hstack((img,up_down)),'comparison')
cv_show(img-up_down,'img-up_down')   #做减法发现仍有区别


#拉普拉斯金字塔
down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_l = img - down_up
cv_show(l_l,'l_l')

out4:
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第22张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第23张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第24张图片

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第25张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第26张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第27张图片
5.轮廓检测

cv2.findContours(img,mode,method)

mode:轮廓检索模式

RETR_EXTERNAL:只检索最外面的轮廓。

RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中。

RETR_CCOMP:检索所有的轮廓,并将他们组织为两层,顶层是各部分的外部边界,第二层是空洞的边界。

RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。(最常用)

method:轮廓逼近方法

CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。

CHAIN_APPROX_SIMPLE:以压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第28张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第29张图片
demo5:

import cv2
import numpy as np

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:\\openCV files\\data\\1\\contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  #转灰度图
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  #阈值函数,二值化为0和255
cv_show(thresh,'thresh')

#binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)   旧版本的open CV返回三个值
#binary就是二值化的图像结果
#contours是轮廓点结果
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) #  新版本的open CV返回两个值
print(np.array(contours).shape)
#hierarchy 层级


#绘制轮廓
#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
#注意需要copy,防止改变原图
draw_img = img.copy()
#画轮廓,在原图像img上绘制,contours表示被画轮廓,-1表示默认把所有的轮廓都画进来,(0, 0, 255)表示BGR,此处用红色线条绘制;2是线条的宽度
res = cv2.drawContours(draw_img, contours, -1,(0, 0, 255), 2)
cv_show(res,'res')

draw_img = img.copy()
res1 = cv2.drawContours(draw_img, contours, 0,(0, 0, 255), 2) #把-1换成0,三角形外轮廓被画出
draw_img = img.copy()
res2 = cv2.drawContours(draw_img, contours, 1,(0, 0, 255), 2) #把-1换成1,三角形内轮廓被画出
cv_show(res1,'res1')
cv_show(res2,'res2')


#轮廓特征
cnt = contours[0] #算轮廓特征需要先把具体的轮廓拿出来
#面积
print(cv2.contourArea(cnt))
#周长,True表示闭合的
print(cv2.arcLength(cnt,True))


#轮廓近似
img = cv2.imread('D:\\openCV files\\data\\1\\contours2.png')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  #转灰度图
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  #阈值函数,二值化为0和255
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) #  新版本的open CV返回两个值
cnt = contours[0] #算轮廓特征需要先把具体的轮廓拿出来

draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1,(0, 0, 255), 2)
cv_show(res,'res')

epsilon = 0.1*cv2.arcLength(cnt,True)  #0.1倍的周长作为近似的阈值,0.1越小,得到的近似轮廓越精准
approx = cv2.approxPolyDP(cnt,epsilon,True)

draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1,(0, 0, 255), 2)
cv_show(res,'res')


#边界矩形
img = cv2.imread('D:\\openCV files\\data\\1\\contours.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  #转灰度图
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  #阈值函数,二值化为0和255
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) #  新版本的open CV返回两个值
cnt = contours[0] #算轮廓特征需要先把具体的轮廓拿出来

x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv_show(img,'img')

area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('轮廓面积与边界矩形比',extent)


#外接圆
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
img = cv2.circle(img, center, radius, (0,255,0), 2)
cv_show(img,'img')

out5:

D:/PyCharm files/openCV/图像轮廓.py:18: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  print(np.array(contours).shape)
(11,)
8500.5
437.9482651948929
轮廓面积与边界矩形比 0.5154317244724715

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第30张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第31张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第32张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第33张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第34张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第35张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第36张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第37张图片
6.模板匹配

补充知识点

cv2.imread(filename, flags=None)

参数:

filename: 图像地址 如: ‘./xxx.png’

flags: 标志位, 表示读取数据的格式,读取彩色可以设为cv2.IMREAD_COLOR(flags=1)

读取灰度图像设为cv2.IMREAD_GRAYSCALE(flags=0),

读取原始图像设为cv2.IMREAD_UNCHANGED(flags=-1)。

模块匹配和卷积原理很像,模块在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。假如原图像是A×B大小,而模板是A×b大小,则输出结果的矩阵是(A-a+1)×(B-b+1)。

TM_SQDIFF:计算平方不同,计算出来的值越小,越相关‘

TM_CCORR:计算相关性,计算出来的值越大,越相关

TM_CCOEFF:计算相关系数,计算出来的值越大,越相关

(以下三种更推荐:)

TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关

TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关

TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第38张图片

demo6:

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

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

#模块匹配
img = cv2.imread('D:\\openCV files\\data\\2\\lena.jpg',0)   #才发现openCV文件路径里不允许有中文路径
template = cv2.imread('D:\\openCV files\\data\\2\\face.jpg',0)   #flags=0,表示读取灰度图像
h,w = template.shape[:2]   #[:2]表示切片,第0个和第1个,高度110,宽度85

print(img.shape)
print(template.shape)
res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)   #TM_SQDIFF让我们关注最小值,即min_loc
print(res.shape)

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
          'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) #最小值,最大值,最小值坐标位置,最大值坐标位置
#minMaxLoc的结果就是列在前,行在后,相当于w前h后
print(min_val)
print(max_val)
print(min_loc)  ##方框左上角的那个点的位置
print(max_loc)

for meth in methods:
    img2 = img.copy()

    # 匹配方法的真值
    method = eval(meth)  # 传入的是数值
    print(method)
    res = cv2.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc  # 左上角的点
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    # 画矩形
    cv2.rectangle(img2, top_left, bottom_right, 255, 2)

    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    plt.subplot(122), plt.imshow(img2, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()


#匹配多个对象
img_rgb = cv2.imread('D:\\openCV files\\data\\2\\mario.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('D:\\openCV files\\data\\2\\mario_coin.jpg', 0)
h, w = template.shape[:2]

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
# 取匹配程度大于80%的坐标
loc = np.where(res >= threshold)
#[::-1],,,loc结果是高度坐标一起在前面列表(行在前),宽度坐标一起在后一个列表(列在后),所以需要倒序,使得宽在前,高在后,zip将单一的坐标两两打包在一起
for pt in zip(*loc[::-1]):  # *表示可选参数
    bottom_right = (pt[0] + w, pt[1] + h)
    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)

cv_show(img_rgb, 'img_rgb')

out6:

(263, 263)
(110, 85)
(154, 179)
39168.0
74403584.0
(107, 89)
(159, 62)
4
5
2
3
0
1

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第39张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第40张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第41张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第42张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第43张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第44张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第45张图片
7.直方图

cv2.calcHist(images, channels, mask, histSize, ranges)

images:原图像格式为uint8或float32.当传入函数时应用中括号[],例如[img]

channels:同样用中括号。如果传入图像是灰度图,它的值是[0],如果是彩色图像,传入的参数可以是[0][1][2],他们分别对应着BGR

mask:掩膜图像。统整幅图像的直方图把它为None.但是如果你想统计图像某一部分的直方图,你就制作一个掩膜图像并使用它

histSize:BIN的数目,也用中括号,比如0-10,11-20,每十个一统计,这个参数指定bin(箱子)的个数,也就是总共有几条条状图

ranges:像素值的范围常为[0256]

demo7:

import cv2
import numpy as np
import matplotlib.pyplot as plt #matplotlib是RGB

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:\\openCV files\\data\\2\\cat.jpg',0)#0表示灰度图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
print(hist.shape)

plt.hist(img.ravel(),256)  #ravel()多维降为一维,一共256个BIN
plt.show()

img = cv2.imread('D:\\openCV files\\data\\2\\cat.jpg')
color = ('b','g','r')
for i,col in enumerate(color):#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
    histr = cv2.calcHist([img],[i],None,[256],[0,256])
    plt.plot(histr,color = col)
    plt.xlim([0,256])


#mask操作
# #创建 mask
mask = np.zeros(img.shape[:2],np.uint8)  #[:2表示二维,不需要将颜色通道加进来;uint8:0-255
mask[100:300, 100:400] = 255   #要保存什么部分,就置为白色,255
cv_show(mask,'mask')

img = cv2.imread('D:\\openCV files\\data\\2\\cat.jpg',0)#0表示灰度图
cv_show(img,'img')

masked_img = cv2.bitwise_and(img,img,mask=mask)#与操作
cv_show(masked_img,'masked_img')

hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])

plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(222),plt.imshow(mask,'gray')
plt.subplot(223),plt.imshow(masked_img,'gray')
plt.subplot(224),plt.plot(hist_full),plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()


#直方图均衡化
img = cv2.imread('D:\\openCV files\\data\\2\\clahe.jpg',0)#0表示灰度图
plt.hist(img.ravel(),256)  #ravel()多维降为一维,一共256个BIN
plt.show()

equ = cv2.equalizeHist(img)  #更亮了,但丢失了不少细节
plt.hist(equ.ravel(),256)
plt.show()

res = np.hstack((img,equ))
cv_show(res,'res')


#自适应直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))#分格均衡化

res_clahe = clahe.apply(img)
res = np.hstack((img,equ,res_clahe))
cv_show(res,'res')

out7:

(256, 1)

基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第46张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第47张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第48张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第49张图片
在这里插入图片描述
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第50张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第51张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第52张图片
基于python的openCV自学笔记(二)——Sobel、Scharr、laplacian、Canny边缘、金字塔、轮廓检测、模板匹配和直方图_第53张图片

你可能感兴趣的:(openCV,python,opencv)