赞
踩
opencv读取的是BGR图像
彩色图:3通道
灰度图:1通道,黑色0——>白色255
二值图:只有黑白两种颜色。
图像的读取有多种方法
传统cv-图像读取与保存_平行世界里的我的博客-CSDN博客
opencv读取的image的形状是【h,w,c],最后一个维度是通道维度
当进行一些不太关注细节的图像处理时,可以只采取单通道来处理,这样就可以减少图像处理的时间和加快项目推进的速度。
两种方法:①是直接选取img[h,w,c]直接切割
②是通过cv2.selectROI("image", img, showCrosshair, fromCenter)鼠标选择ROI
RGB空间
灰度图
LAB
HSV(Hue-色调、Saturation-饱和度、Value-值)将亮度从色彩中分解出来,在图像增强算法中用途很广,在很多图像处理任务中,经常将图像从RGB色彩空间转换到了HSV色彩空间,以便更好地感知图像颜色,利用HSV分量从图像中提取感兴趣的区域。
应用:要提取某个目标,可以通过设置HSV色彩空间的高低阈值来做。
HSV模型简介以及利用HSV模型随机增强图像_太阳花的小绿豆的博客-CSDN博客_hsv模型
两种方式:①cv2.addWeighted(img1,0.7,img2,0.3,0)
这种方法只能两张图片混合
图像混合其实也是加法,但是不同的是两幅图像的权重不同。图像混合的计算公式如下:g(x) = (1-α)f0{x}+αf1{x}+γ, α取值在0~1之间 ,g(x)表示最终的图像(混合后的图像),f0{x}和f1{x}表示两幅图像,可以看到前面的参数是1-α和α,和为1,我们这里取得都是0.5,0.5+0.5=1,后面的γ参数 一般默认为0。
②按位运算,可以实现特定位置的图像融合,而且不一定是矩形roi
cv2.bitwise_and()、cv2.bitwise_or()、cv2.bitwise_not() 和 cv2.bitwise_xor()
这段代码没怎么读懂?
①仿射变换——平移
temp = np.float32([[1, 0, -5], [0, 1, -20]]) 向左平移5个像素, 向上平移50个像素
cv2.warpAffine(img, temp, (img_width, img_height))
②仿射变换——旋转
# 围绕原点 逆时针旋转40度
M = cv2.getRotationMatrix2D(center=center, angle=40, scale=1.0)
rotated_40 = cv2.warpAffine(img, M, (img_width, img_height))
①仿射变换——缩放:
cv2.resize(img, new_size)
②仿射变换——翻转:也就是对称,
1 水平翻转 Horizontally , 0 垂直翻转 *Vertically ,-1 同时水平翻转与垂直反转 Horizontally & Vertically
cv2.flip(img1, 1) #水平
数据增广:旋转,缩放,平移以及错切_太阳花的小绿豆的博客-CSDN博客_数据增广中旋转
- # 1 水平翻转 Horizontally
- # 0 垂直翻转 *Vertically
- # -1 同时水平翻转与垂直反转 Horizontally & Vertically
-
-
- # 实现水平翻转
- fz_1 = cv2.flip(img1, 1)
- # 显示
- cv2.imshow("fz_1", fz_1)
-
- # 垂直翻转
- fz_2 = cv2.flip(img2, 0)
- cv2.imshow("fz_2", fz_2)
-
- # 同时水平翻转与垂直反转
- fz_3 = cv2.flip(img3, -1)
- cv2.imshow("fz_2=3", fz_3)

腐蚀和膨胀在灰度上进行操作。
腐蚀:消除一些孤立点,消除一些边界点,使边界向内收缩。出现白色噪点时通常用这种。(黑多白少)
- # 定义腐蚀核
- fushi_kernel = np.ones((5, 5), np.uint8)
- # 调用腐蚀函数,第一个为需要腐蚀的原始图像,第二个为腐蚀框(核)的大小,并不是越大或者越小越好,而是要实际测试,选择最合适的,第三个参数为迭代次数,也就是重复腐蚀的次数,这个也可以自己定义。
- fushi_image = cv2.erode(src_img, fushi_kernel, iterations=1)
膨胀:(白多黑少)
- # 定义膨胀核
- PZ_kernel = np.ones((3, 3), np.uint8)
- # 调用膨胀函数 第一个为需要膨胀的原始图像,第二个为膨胀框的大小,第三个为迭代次数,这里设置为1 ,粉丝们可以自行设置哦
- PZ_image = cv2.dilate(src_img, PZ_kernel, iterations=1)
开闭运算在灰度图上进行操作。
开运算:先腐蚀再膨胀——去除噪点
- # 定义操作框,在图像上以这个框大小的像素进行遍历开运算
- operation_kernel = np.ones((3, 3), np.uint8)
- # 开运算 【处理的图像,处理图像的方式,处理的核大小,处理的次数】
- result_image = cv2.morphologyEx(img, cv2.MORPH_OPEN, operation_kernel, iterations=iter_times)
闭运算:先膨胀再腐蚀——填充图像中的空洞,衔接相邻的部分。
- # 定义操作框,在图像上以这个框大小的像素进行遍历闭运算
- operation_kernel = np.ones((3, 3), np.uint8)
- # 闭运算
- result_image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, operation_kernel, iterations=iter_time)
OpenCV图像处理(十一)---图像梯度 sobel算子,scharr算子,Laplacian算子
梯度:在图像上表示为提取图像的边缘(横向、纵向)。
图像梯度的本质:当前方向上相邻像素的差值。
- 一共三个参数,第一个是需要计算梯度的图像,第二个是图像的数据格式,第三个参数为1,0或者0,1,分别对应x方向与y方向,一般情况下,单独梯度计算出来后都会进行叠加以增强效果,因此叠加函数就排上了用场,由于各自取一半的可信度,因此,权重都为0.5
- # x 方向梯度
- image_grad_x = cv2.Scharr(image, cv2.CV_32F, 1, 0)
- # y 方向梯度
- image_grad_y = cv2.Scharr(image, cv2.CV_32F, 0, 1)
- # 分别求绝对值并转化为8位的图像上,这样做方便显示
- image_gradx = cv2.convertScaleAbs(image_grad_x)
- image_grady = cv2.convertScaleAbs(image_grad_y)
- # 两个方向梯度的叠加,权重各自一半
- image_gradxy = cv2.addWeighted(image_gradx, 0.5, image_grady, 0.5, 0)
阈值化是在灰度图上进行处理。(但是opencv画出来的却是彩色图)
- image_gray = cv2.cvtColor(coor_image, 0)
-
- gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
这两个不一样,上面那个并不是转换为了灰度图,下面那个才是灰度图。
阈值化就是二值化,就是将图像上每一个像素点的像素值设置为一个定值,一般为0(黑色)或255(黑色),最后呈现出黑白的效果。
下面的属于固定阈值
- # 函数第四个参数采用 cv2.THRESH_BINARY_INV
- # 阈值为50,大于50的像素值设定为0, 小于的就是200
- what1, image_thresh_50 = cv2.threshold(image_gray, 50, 200, cv2.THRESH_BINARY_INV)
- print("what1:{}".format(what1))
- cv2.imshow("dst_thresh_50", image_thresh_50)
-
- # -----------------实例二----------------------
-
- # 函数第四个参数采用cv.THRESH_BINARY
- # 阈值为30,大于30的的像素值设定为230(一般为白色) 小于30的就是0像素值
- what2, image_thresh_30 = cv2.threshold(image_gray, 30, 230, cv2.THRESH_BINARY)
- # 打印看看返回值是啥?
- print("what2:{}".format(what2))
- cv2.imshow("dst_thresh_30", image_thresh_30)
-
- # #-----------------实例三----------------------
- # 函数第四个参数采用 cv2.THRESH_TRUNC
- # 截断 大于70的像素值设定为70 小于70的像素不变
- what3, image_thresh_70 = cv2.threshold(image_gray, 70, 180, cv2.THRESH_TRUNC)
- print("what3:{}".format(what3))
- cv2.imshow("dst_thresh_70", image_thresh_70)
-
- # #-----------------实例四----------------------
- # 截断 小于140的像素值设定为140 大于140的像素值不变
- what4, image_thresh_140 = cv2.threshold(image_gray, 140, 200, cv2.THRESH_TOZERO)
- print("what4:{}".format(what4))
- cv2.imshow("dst_thresh_140", image_thresh_140)

不同类型的阈值效果也不同。
阈值化对于去除噪点还有图像分割等都会涉及。
全局阈值:
- ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_TRIANGLE)
- # ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE) 与上一行代码是同一个意思,| cv.THRESH_TRIANGLE 就是调用这种方法来算阈值
- print("TRIANGLE自适应阈值:%s" % ret)
- cv.imshow("TRIANGLE", binary)
-
- ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)
- print("OTSU自适应阈值:%s" % ret)
- cv.imshow("OTSU", binary)
-
- ret, binary = cv.threshold(gray, 200, 255, cv.THRESH_TRUNC)
- print("TRUNC截断阈值:%s" % ret)
- cv.imshow("TRUNC_200", binary)
-
- ret, binary = cv.threshold(gray, 100, 255, cv.THRESH_TOZERO)
- print("TOZERO归零阈值:%s" % ret)
- cv.imshow("TOZERO_100", binary)

全局阈值效果不佳,OTSU阈值优于其他固定阈值。
局部阈值:
- binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 5, 6)
- cv.imshow("adapt_Mean", binary)
- binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 5, 6)
- cv.imshow("adapt_GAUSSIAN", binary)
不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。有:①局部邻域块的均值 ②局部邻域块的高斯加权和。
自算阈值:
比如计算灰度图的平均值作为阈值化的阈值
Python-Opencv中阈值化操作和自适应阈值化,二值化操作_wave.lt的博客-CSDN博客_python opencv 自适应阈值二值化
滤波:对各种数字信号中的某一或指定频率进行过滤。过滤掉不需要的像素,尽量使之平均,不至于高低不平。
- # 定义滤波核大小
- filter_kernel = np.ones((3, 3), np.float32) / 9
- # 调用2D滤波器函数,跟之前一样,我们不用重点解释了,直接带参数就行
- # 感兴趣的可以查看其他参数代表含义
- dst_img = cv2.filter2D(read_image, -1, filter_kernel)
滤波后的图像变模糊
均值滤波:归一化卷积模板
- # 均值滤波
- image_blur = cv2.blur(img, (3, 3)) # 模板大小为3*3, 可自定义
高斯双边滤波:
- # 后面两个数字:空间高斯函数标准差,灰度值相似性标准差
- dst =cv2.bilateralFilter(img ,15 ,35 ,35)
滤波的作用之一是降噪?
OpenCV图像处理(十四)---边缘检测 边缘检测算子(Roberts算子、Prewitt算子、Sobel算子 和 Laplacian算子)
处理的是灰度图。
边缘检测实际就是检测图像中亮度变化有区别或者较大的地方,实际效果表现为图像中的轮廓检测。
一阶导数边缘算子:以最大值作为对应的边缘的位置。有Roberts算子、Sobel算子和Prewitt算子。
Roberts算子:用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。缺点:对边缘的定位不太准确,提取的边缘线条较粗。
dx表示水平方向,dy表示垂直方向。
- # 灰度化处理图像
- grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
-
- # Roberts算子
- kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
- kernely = np.array([[0, -1], [1, 0]], dtype=int)
- x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
- y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
- # 转uint8
- absX = cv2.convertScaleAbs(x)
- absY = cv2.convertScaleAbs(y)
- Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
Prewitt算子:利用特定区域内像素灰度值产生的差分实现边缘检测。适合用来识别噪声较多、灰度渐变的图像。
- # 灰度化处理图像
- grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
-
- # 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(grayImage, cv2.CV_16S, kernelx)
- y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
- # 转uint8
- absX = cv2.convertScaleAbs(x)
- absY = cv2.convertScaleAbs(y)
- Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。
Sobel算子:用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过某个数的特定点记为边缘。
- # 灰度化处理图像
- grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
-
- # Sobel算子
- x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0) # 对x求一阶导
- y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1) # 对y求一阶导
- absX = cv2.convertScaleAbs(x)
- absY = cv2.convertScaleAbs(y)
- Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
二阶导数的边缘算子:以过零点作为对应边缘的位置。有Laplacian算子,对噪声敏感。常用于图像增强领域和边缘提取。
- # 灰度化处理图像
- grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
-
- # 拉普拉斯算法
- dst = cv2.Laplacian(grayImage, cv2.CV_16S, ksize=3)
- Laplacian = cv2.convertScaleAbs(dst)
其他边缘算子:在满足一定约束条件下推到出来的边缘检测最优化算子,有canny算子。
- # 读取图片转换为为灰度图像
- image_gray = cv2.cvtColor(src_image, cv2.COLOR_BGR2GRAY)
- # 边缘检测之前先进行滤波,降噪,滤波方式为高斯滤波
- filter_image = cv2.GaussianBlur(image_gray, (5, 5), 0)
- # 调用canny算子,进行边缘检测 48,170是一个调整范围,根据实际情况选用
- canny_image = cv2.Canny(filter_image, 48, 170) # 48是最小阈值,170是最大阈值
sobel算子检测结果更接近于实际感觉,canny算子更清晰,实际用到的时候再来具体考虑,一般优先使用canny算子。
使用cv2.findContours()函数来查找检测物体的轮廓。
对阈值化图像进行轮廓检测。
- ret, binary = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)
- cv2.imshow("binary", binary)
-
- contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- cv2.drawContours(img, contours, -1, (0, 0, 255), 3)
框选函数:圆形,矩形等。
去除不必要的轮廓,通常用面积法、宽高法等。
直方图(灰度直方图、掩膜的应用、直方图均衡化、自适应直方图均衡化)
直方图:用来比较不同的图像。有两种不同实现:matplotlib和opencv
灰度直方图:描述图像中灰度的分布情况,横轴表示像素的灰度范围(0-255),纵轴表示像素的数量或者密度。
- # 以灰度模式读入图片
- gray_img = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)
- cv2.imshow("gray_img", gray_img)
-
- # 调用hist函数绘制直方图
- # .ravel()拉成一维数组
- plt.hist(gray_img.ravel(), 256)
- # 显示直方图
- plt.show()
- # 以灰度模式读入图片
- gray_img = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)
-
- # 调用cv2.calcHist()函数绘制直方图
- # cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
- # mask : 掩码图像,统计整幅图像的直方图,设为None。统计图像某一部分的直方图时,需要掩码图像
- # histSize : BINS的数量
- # accumulate : 累计标识,默认值为false,如果被设置为true,则直方图在开始分配时不会被清零
- hist = cv2.calcHist([gray_img], [0], None, [256], [0, 255])
不知道为什么opencv中的实现方法里面参数都要用[]括起来,不用的话,结果是不一样的。
- images:输入的图像
- channels:选择图像的通道,如果是三通道的话就可以是[0],[1],[2]
- mask:掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,如果有mask,会先对输入图像进行掩膜操作
- histSize:使用多少个bin(柱子),一般为256,但如果是H值就是181
- ranges:像素值的范围,一般为[0,255]表示0~255,对于H通道而言就是[0,180]
需要注意的是,这里除了mask以外,其余的几个参数都要加上[],如下所示:
hist=cv2.calcHist([img],[0],mask,[181],[0,180])
OpenCV图像处理(十七)---图像直方图均衡化 彩色图像的直方图均衡化
均衡化:使图像的像素值尽量分布均匀,而不是高低差落很大。目的是更好的观察图像的细节部分。适合处理背景或前景都太亮或者太暗的图像、x光图像中骨骼结构以及曝光过度或者曝光不足的照片。
均衡化对原始图的灰度图进行处理。也可以对彩色图进行处理
- # 直方图均衡化,调用cv2.equalizeHist 函数实心
- result_img = cv2.equalizeHist(gray_img)
cv2.equalizeHist 函数是对全局均衡化。
均衡化后的图像提升了对比度,色彩变得充实起来。
在实际项目中,为了不对全局造成变化,仅仅对目标区域进行操作,先进行ROI区域选择。
在最后,这篇博文说道可以进行彩色图均衡化,但是我实验读取彩色图并不能进行处理?——在第二篇博文里有介绍。分别对RGB通道做均衡化
OpenCV图像处理(十八)---图像之模板匹配 cv2.matchTemplate模板匹配和cv2.minMaxLoc()函数 cv2.rectangle
模板匹配:事先有一个模板然后利用这个模板与别的图像进行比对,最终的目的是在别的图像中找到我们事先准备好的模板。
- # 调用函数matchTemplate()进行模板匹配
- 第一第二两个参数是原始图像和模板图像,匹配的方式是第三个参数,这里我们选择了cv2.TM_SQDIFF_NORMED,当然还有其他的匹配方式,我们选择了较为常用的。
- process_img = cv2.matchTemplate(src_img, key_img, cv2.TM_SQDIFF_NORMED)
OpenCV图像处理(十九)---霍夫变换 cv2霍夫圆环检测(HoughCircle)
霍夫变换:为了找出物体的形状,包括直线、圆形、椭圆等。
- # 调用霍夫变换函数找到图像中的圆圈
- circles = cv2.HoughCircles(gray_img, cv2.HOUGH_GRADIENT, 1, 125,
- param1=90, param2=68, minRadius=0,maxRadius=90)
- circles = np.uint16(np.around(circles))
- for i in circles[0, :]:
- # 画出圆圈的外圈,(0, 255, 0)表示BGR中的绿色(G=255)
- cv2.circle(src_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
- # 画出圆心(0, 0, 255)表示BGR中的红色(R=255)
- cv2.circle(src_img, (i[0], i[1]), 2, (0, 0, 255), 3)
- cv2.imshow("huofu_cicle", src_img)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。