OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图
OpenCV基础
- 1. Morphological Transformations(形态变换)
- 2. Image Pyramids(图像金字塔)
- 3. Contours(轮廓)
- 4. 轮廓的特性进阶
- 5. Histograms(直方图)
- 5.1 opencv计算直方图
- 5.2 Numpy计算直方图
- 6. 源码
- 6.1 金字塔源码(高斯、拉普拉斯)
- 6.2 直方图源码(自适应均衡化,CLAHE均衡化)
- 参考
1. Morphological Transformations(形态变换)
(1)腐蚀(丢弃边缘,变小)
(2)膨胀(增加边缘,变大)
(3)打开(对轮廓外部的噪点可丢弃)
(4)关闭(对轮廓内部的噪点可丢弃)
(5)形态梯度(Morphological Gradient 侵蚀与腐蚀的差值图)
(6)Top Hat(原图与打开之间的差值图)
(7)Black Hat(原图与关闭之间的差制图)
获取不同的卷积核:
cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
第一个参数:卷积核形状
第二个参数:卷积核大小
2. Image Pyramids(图像金字塔)
金字塔的一种应用是图像融合,实现图像间的无缝融合;
具有不同分辨率的图像集称为“图像金字塔”(因为当它们堆叠在堆栈中时,底部最大的图像和顶部最小的图像看起来像金字塔)。
高斯金字塔中的较高级别(低分辨率)是通过删除较低级别(较高分辨率)图像中的连续行和列而形成的。然后,较高级别的每个像素由基础级别的5个像素的贡献与高斯权重形成。通过这样做,M×N图像变成M / 2×N / 2图像。因此面积减少到原始面积的四分之一。它称为八度。当我们在金字塔中越靠上时(即分辨率下降),这种模式就会继续。同样,在扩展时,每个级别的面积变为4倍。我们可以使用cv2.pyrDown()和cv2.pyrUp()函数找到高斯金字塔。
分类:
(1)高斯金字塔
(2)拉普拉斯金字塔(高斯金字塔相邻俩层之间的差值构成)
拉普拉斯金字塔由高斯金字塔形成。没有专用功能。拉普拉斯金字塔图像仅像边缘图像。它的大多数元素为零。它们用于图像压缩。拉普拉斯金字塔的层由高斯金字塔的层与高斯金字塔的高层的扩展版本之间的差形成。
3. Contours(轮廓)
1. 轮廓是什么?怎么查找绘制?
2. 轮廓的特征(例如面积,周长,质心,边界框等)的计算
3. 轮廓的更多方法:层次等
轮廓可以简单地解释为连接具有相同颜色或强度的所有连续点(沿边界)的曲线。轮廓是用于形状分析以及对象检测和识别的有用工具。
查找轮廓 cv2.findContours
绘制轮廓 cv2.drawContours
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
入参
- thresh: 源图像
- cv2.RETR_TREE:轮廓检索模式
- cv2.CHAIN_APPROX_SIMPLE:轮廓近似方法,如果传递cv2.CHAIN_APPROX_NONE,则将存储所有边界点。如果传递cv2.CHAIN_APPROX_SIMPLE,则只是返回角点;(如矩形返回4个点但前一个方法返回所有组成的点;)
img = cv2.drawContours(img, contours, -1, (0,255,0), 3)
- img: 要绘制的源图像
- contours: 绘制的轮廓
- -1:绘制所有的轮廓,3绘制出第四个轮廓
- (0,255,0):颜色BGR 绿色
- 3:画笔的粗细
特征的计算: cv2.moments()提供了所有计算出的矩值的字典。
质心:cx = int(M[‘m10’]/M[‘m00’])
cy = int(M[‘m01’]/M[‘m00’])周长:perimeter = cv2.arcLength(cnt,True)
面积:area = cv2.contourArea(cnt) 或者 M[‘m00’]
轮廓近似
根据我们指定的精度,它可以将轮廓形状近似为顶点数量较少的其他形状。
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
表示以110%的周长拟合轮廓;外接凸包:hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]
检查凸度:k = cv2.isContourConvex(cnt) 返回True或者False
直边界外接矩形(外接矩形):
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)面积最小外接矩形:
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
im = cv2.drawContours(im,[box],0,(0,0,255),2)最小外接圆:
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)拟合椭圆
ellipse = cv2.fitEllipse(cnt)
im = cv2.ellipse(im,ellipse,(0,255,0),2)拟合线
rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
4. 轮廓的特性进阶
宽高比:
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w)/h扩充:是轮廓占其外接矩形的面积比;
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area坚固度:是轮廓占其凸包的面积比;
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area等效直径:是面积与轮廓面积相同的圆的直径。
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)Orientation方向:是物体指向的角度。以下方法还给出了主轴和副轴的长度。
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)蒙版和像素点:构成某轮廓的所有点
mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)最大值,最小值及位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)平均强度(灰度模式下的平均颜色或者说平均强度)
mean_val = cv2.mean(im,mask = mask)极端点:是指对象的最顶部,最底部,最右侧和最左侧的点;
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
5. Histograms(直方图)
(1)什么是直方图?直方图的查找,绘制?
(2)直方图均衡化,优化对比度受限的自适应直方图均衡
直方图可以视为图形或曲线图,从而可以总体了解图像的强度分布。它是在X轴上具有像素值(不总是从0到255的范围),在Y轴上具有图像中相应像素数的图。
5.1 opencv计算直方图
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
- images: 源图像
- channels: 图像通道,灰度图0,彩色RGB
- mask:要分析的蒙版区域
- histSize:x轴的分组数
- ranges:x轴的范围
5.2 Numpy计算直方图
hist, bins = np.histogram(img.ravel(), 256, [0, 256])
hist2 = np.bincount(img.ravel(), minlength=256)
np.bincount() 比 np.histogram() 快10倍
OpenCV函数比np.histogram() 快(大约40倍),因此坚持使用OpenCV功能。
直方图均衡化: 使图像像素更平均一些;
直方图均衡化的一个弊端:对于区域比较大且同时包含较亮、较暗的区域时,效果不好,优化是使用CLAHE;
CLAHE(Contrast Limited Adaptive Histogram Equalization) 对比度受限的自适应直方图均衡
对于细节方面将保留的更多 相当于在每一个8*8像素区域内均衡
6. 源码
6.1 金字塔源码(高斯、拉普拉斯)
import cv2
import numpy as np
from matplotlib import pyplot as pltA = cv2.imread('D:/imageProcessing/input/flower3.jpg')
B = cv2.imread('D:/imageProcessing/input/flower2.jpg')# 由于大小不同的图片后边拉普拉斯算子相减会报错 先缩放到同样大小
A = cv2.resize(A, (32 * 32, 32 * 32))
B = cv2.resize(B, (32 * 32, 32 * 32))
print(A.shape)
print(B.shape)# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in range(6):G = cv2.pyrDown(G)gpA.append(G)# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in range(6):G = cv2.pyrDown(G)g = cv2.cvtColor(G, cv2.COLOR_BGR2RGB)plt.subplot(1, 6, (i + 1)), plt.imshow(g), plt.title('gpB' + str(i))gpB.append(G)
plt.show()# generate Laplacian Pyramid for A
lpA = [gpA[5]]
for i in range(5, 0, -1):GE = cv2.pyrUp(gpA[i])L = cv2.subtract(gpA[i - 1], GE)lpA.append(L)# generate Laplacian Pyramid for B
lpB = [gpB[5]]
for i in range(5, 0, -1):GE = cv2.pyrUp(gpB[i])L = cv2.subtract(gpB[i - 1], GE)l = cv2.cvtColor(L, cv2.COLOR_BGR2RGB)plt.subplot(1, 6, (i + 1)), plt.imshow(l), plt.title('lpB' + str(i))lpB.append(L)
plt.show()# Now add left and right halves of images in each level
LS = []
for la, lb in zip(lpA, lpB):rows, cols, dpt = la.shapels = np.hstack((la[:, 0:int(cols / 2)], lb[:, int(cols / 2):]))LS.append(ls)# now reconstruct
ls_ = LS[0]
for i in range(1, 6):ls_ = cv2.pyrUp(ls_)ls_ = cv2.add(ls_, LS[i])# image with direct connecting each half
real = np.hstack((A[:, :int(cols / 2)], B[:, int(cols / 2):]))# 由于python-opencv图片是BGR通道,matplot展示需要是RGB,先转换下颜色空间
ls_ = cv2.cvtColor(ls_, cv2.COLOR_BGR2RGB)
real = cv2.cvtColor(real, cv2.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(ls_), plt.title('Pyramid_blending2')
plt.subplot(122), plt.imshow(real), plt.title('Direct_blending')
plt.show()
6.2 直方图源码(自适应均衡化,CLAHE均衡化)
# 直方图均衡化: 使图像像素更平均一些;
# 直方图均衡化的一个弊端:对于区域比较大且同时包含较亮、较暗的区域时,效果不好,优化是使用CLAHE
# CLAHE(Contrast Limited Adaptive Histogram Equalization) 对比度受限的自适应直方图均衡
# 对于细节方面将保留的更多 相当于在每一个8*8像素区域内均衡import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)hist, bins = np.histogram(img.flatten(), 256, [0, 256])cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 256, [0, 256], color='r')
plt.xlim([0, 256])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.show()# cdf
cdf_m = np.ma.masked_equal(cdf, 0)
cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
cdf = np.ma.filled(cdf_m, 0).astype('uint8')
img2 = cdf[img]
plt.subplot(221), plt.imshow(img, cmap=plt.cm.gray)
plt.subplot(222), plt.imshow(img2, 'gray')
plt.subplot(223), plt.imshow(img)
plt.subplot(224), plt.imshow(img2)
plt.show()# openCV中的直方图均衡
img = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)
equ = cv2.equalizeHist(img)
res = np.hstack((img, equ)) # stacking images side-by-side
plt.subplot(221), plt.imshow(img), plt.title('Origin gray')
plt.subplot(222), plt.imshow(equ), plt.title('Equalization res')
plt.subplot(223), plt.imshow(res)# CLAHE(Contrast Limited Adaptive Histogram Equalization) 对比度受限的自适应直方图均衡
# 对于细节方面将保留的更多 相当于在每一个8*8像素区域内均衡
img = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)
# create a CLAHE object (Arguments are optional).
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
plt.subplot(224), plt.imshow(cl1), plt.title('CLAHE res')
plt.show()
参考
- https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops
OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图相关推荐
- 如何把OpenCV Python获取的图像传递到C层处理
原文:https://blog.csdn.net/yushulx/article/details/52788051 用OpenCV Python来开发,如果想要用到一些C/C++的图像处理库,就需要创 ...
- 使用OpenCV python模块读取图像并将其另存为灰度系统
In Python, we can use an OpenCV library named cv2. Python does not come with cv2, so we need to inst ...
- OpenCV之imgproc 模块. 图像处理(1)图像平滑处理 腐蚀与膨胀(Eroding and Dilating) 更多形态学变换 图像金字塔 基本的阈值操作
图像平滑处理 目标 本教程教您怎样使用各种线性滤波器对图像进行平滑处理,相关OpenCV函数如下: blur GaussianBlur medianBlur bilateralFilter 原理 No ...
- OpenCV_04 几何变换:图像缩放+图像平移+图像旋转+仿射变换+透射变换+图像金字塔
1 图像缩放 缩放是对图像的大小进行调整,即使图像放大或缩小. API cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR) 参 ...
- 【opencv学习】【图像金字塔】
今天简单学习下图像金字塔,说白了就是图像放大缩小的一些方法,但是是等比例的. import cv2 import numpy as np# 展示图像,封装成函数 def cv_show_image(n ...
- opencv python matplotlib.pyplot.hist() 如何绘制灰度直方图,如何根据灰度直方图确定最优二值化值
什么是灰度直方图? 图像直方图(histogram)是图像的统计学特征,常用于了解图像的基本特征以便分析.不过图像的直方图不具有空间特征. 图像的灰度直方图(histogram),就是将图像转化成灰度 ...
- OpenCV-Python图像形态变换概述及morphologyEx函数介绍
☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一.形态变换概念 图像形态变换又称为形态学图像处理.图像形态学,它是基于数学形态学(Mat ...
- OpenCV Python教程(2、图像元素的访问、通道分离与合并)
OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...
- python图像边缘检测_使用python获取图像中形状的轮廓(x,y)坐标
我需要使用python获得下面图像的轮廓坐标(x,y)的矩阵.使用python获取图像中形状的轮廓(x,y)坐标 我尝试用OpenCV的精明探测器和发现的轮廓,但我得到了很多的轮廓,我不知道如何让一个 ...
- opencv 图像金字塔
文章目录 概念 一.opencv 函数支持 概念 图像金字塔: 图像金字塔是图像的集合,所有图像都来自单个原始图像,这些图像被连续下采样,直到达到某个所需的停止点. 有两种常见的图像金字塔: 高斯金字 ...
最新文章
- Wireshark命令行工具tshark使用小记
- 2021牛客多校7 - xay loves monotonicity(线段树区间合并)
- 关于发那科机器人的FSSB
- c++ windows console 快速编辑模式 关闭
- 三、面向对象(高琪java300集+java从入门到精通笔记)
- 【BlueZ】【蓝牙】跨平台实现Ble MasterSlaveMesh 之Linux篇-1
- 电子科技大学计算机博士要求,博士研究生发表论文的要求-电子科技大学.PDF
- CIMPLICITY 历史数据存储及趋势显示示例
- [SCOI2009]粉刷匠 DP)
- 寒冬降临程序猿们如何过冬
- java库函数-----Math库函数(每日一更)
- SQL语句的约束条件
- 弹性盒子内容体居右对其_弹性盒子基本属性
- Artificial Intelligence A Modern Approach 第二版笔记(一)
- 三路测径仪同时测量三根铜丝的外径
- 海云安SCA平台迎来新升级 助力企业全面透视开源组件安全风险
- makefile include的作用
- 红队工具合集,安全er值得拥有
- 大作业,但是图片不会传
- 物联网亿万级通信一站式解决方案EMQ