Day03计算机视觉Open Cv

一、图像轮廓

1.图像轮廓

#边缘检测可以把图像的边缘检测出来,但是边缘是不连续的
#将边缘连接成一个整体,构成轮廓

#图像轮廓注意事项
#1.图像轮廓处理的对象是二值图像,需要预先进行阈值分割(得到二值图像)或者边缘检测(Canny边缘检测得到的图像就是黑白的)
#2.查找轮廓的时候会改变原始图像,需要将原始图像备份
#3.在openCv中二值图像白色是前景,黑色是背景或者孔。所以,对象必须是白色,背景必须是黑色,否则就转换。

#寻找图像的轮廓信息函数:cv2.findContours
#image,contours,hierarchy=cv2.findContours(原始图像,轮廓检索模式,轮廓的近似方法)
#image是修改后的原始图像,contours是轮廓,hierarchy是图像的拓扑信息(轮廓层次)
#轮廓检索模式:cv2.RETR_TREE
#cv2.RETR_EXTERNAL:表示只检索外轮廓
#cv2.RETR_LIST:检测的轮廓不建立等级关系
#cv2.RETR_CCOMP:建立两个等级的轮廓,上面一层是外边界,里面一层是内孔的边界信息。
# 如果内孔里面还有一个连通物体,这个物体的边界也在顶层
#cv2.RETR_TREE:建立一个等级树的轮廓:一般都用这个
#轮廓的近似方法
#cv2.CHAIN_APPROX_NONE:存储所有的轮廓点
#cv2.CHAIN_APPROX_SIMPLE:压缩水平、垂直方向、对角线方向的元素,只保留该方向的终点坐标。例如一个矩形轮廓只用四个点保存轮廓信息

#cv2.drawContours():绘制图像的轮廓信息
#dst=cv2.drawContours(原始图像,contours,contourldx,colour,thickness)
#contours是绘制的轮廓的数组,contourldx是需要绘制的边缘索引,如果全部绘制就-1
#color是绘制的颜色,为BGR格式的,thickness是画笔的粗细

import cv2
import numpy as np
img=cv2.imread("/Users/macbook/Desktop/face.png")#原始图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换成灰度图像
ret,binary=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#转换成二值图像
cv2.imshow("original",img)

#寻找轮廓信息:树结构等级关系,压缩水平、垂直、对角线方向的元素
img1,contours,hierarchy=cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#绘制轮廓信息的时候,原始图像会发生改变,要把原始图像复制一份
img_changed=img.copy()#**************************************************************
#绘制轮廓信息:用红色的厚度为1的画笔画出全部的外轮廓
result=cv2.drawContours(img_changed,contours,-1,(0,0,255),1)
cv2.imshow("result",result)

cv2.waitKey(0)
cv2.destroyAllWindows()

二、直方图

1.直方图的基本概念

#直方图:
#横坐标是图像中各个像素点的灰度级,纵坐标是该灰度级的像素个数
#归一化直方图:
#横坐标是图像中各个像素点的灰度级,纵坐标是该灰度级出现的概率,就是用个数/像素点总数

#概念:DIMS:使用参数的数量,灰度直方图就是1;BINS参数子集的数目;Range:一般就是【0,255】

2.绘制直方图

#hist函数用来绘制直方图
#hist(数据源,像素级)
#数据源:图像,必须是一维数组   数据源=原始图像.ravel()
#像素级一般是256,即[0,255]

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)
cv2.imshow("original",img)
#绘制灰度直方图,直接就会绘制出来
plt.hist(img.ravel(),256)

cv2.waitKey(0)
cv2.destroyAllWindows()

3.使用opencv统计直方图和绘制

#使用opencv统计直方图
#hist=cv2.calcHist(image,channels,mask,histSize,ranges,accumulate)
#hist是返回值:返回的是直方图,本质上是一个一维数组,不是真正意义上的直方图
#image是原始图像,要用[]使用
#channels:指定通道,灰度图像直接就是[0],彩色图像[0][1][2]分别对应BGR
#mask:掩码图像。统计整幅图像的直方图,就用none;统计图像某一部分的直方图,就用掩码图像
#histSize:BINS的数量,一般是[256]
#ranges:像素值的范围,一般就是[0,255]
#accumulate:默认是false。如果是true,可以用于从多个对象中绘制单个直方图,或者用于实时更新直方图


#绘制直方图
#plt.plot(统计直方图的结果,颜色)

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png")

#使用opencv统计直方图
#蓝色通道的统计直方图
histb=cv2.calcHist([img],[0],None,[256],[0,255])#默认accumulate是false
#绿色通道的统计直方图
histg=cv2.calcHist([img],[1],None,[256],[0,255])
#红色通道的统计直方图
histr=cv2.calcHist([img],[2],None,[256],[0,255])

#绘制opencv统计直方图
plt.plot(histb,color='b')#绘制颜色是蓝色的蓝色通道的直方图
plt.plot(histg,color='g')#绘制颜色是绿色的绿色通道的直方图
plt.plot(histr,color='r')#绘制颜色是红色的红色通道的直方图

4.使用掩膜的直方图Mask

#生成一个与原始图像大小相同的黑色的图像 mask=np.zeros(image.shape,np.uint8)
#在黑色图像上再添加一张白色的图片 mask[x1:x2,y1:y2]=255
#掩膜之后图片的处理结果就是只保留图片在掩膜白色区域的部分,用来针对图片中的某一部分处理

import import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#生成掩膜
mask=np.zeros(img.shape,np.uint8)#生成与原始图像大小相同的黑色图片
mask[200:400,200:400]=255#掩膜的中间区域是白色

#有掩膜的直方图
hist=cv2.calcHist([img],[0],mask,[256],[0,255])
#没有掩膜的直方图
hist1=cv2.calcHist([img],[0],None,[256],[0,255])
#绘制有掩膜的直方图
plt.plot(hist)
#绘制没有掩膜的直方图
plt.plot(hist1)

5.掩膜图像的处理

#掩膜之后图片的处理结果就是只保留图片在掩膜白色区域的部分,用来针对图片中的某一部分处理
#生成一个与原始图像大小相同的黑色的图像 mask=np.zeros(image.shape,np.uint8)
#在黑色图像上再添加一张白色的图片 mask[x1:x2,y1:y2]=255

#生成掩膜图像  cv2.bitwise_and(img,mask)
#mask就是掩膜图像,img是原始图像

import cv2
import numpy as np
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#构建掩膜图像
mask=np.zeros(img.shape,np.uint8)
mask[50:100,50:100]=255

#生成掩膜图像
result=cv2.bitwise_and(img,mask)

cv2.imshow("result",result)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.直方图均衡化原理

#直方图的均衡化处理原因:
#如果一幅图像占有全部可能的灰度级,并且均匀分布。那么该图像就会有高对比度和多变的灰色色调。图像的细节会更加丰富,质量更高

#直方图均衡化的算法:
#1.计算统计直方图,对统计直方图进行归一化处理,并且逐步加和得到累计直方图
#2.将累计直方图进行区间转换:将累计直方图中的纵坐标乘上255得到像素值结果,新的横坐标就是该结果,纵坐标就是原来的概率
#3.在累计直方图中,概率相近的原始值,会被处理成相同的值

#应用场景:医疗图像识别、车牌识别、人脸识别

#函数:cv2.equalizeHist(scr)

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#直接绘制直方图,不进行均衡化处理
plt.hist(img.ravel(),256)

plt.figure()#创建新的窗口

#进行均衡化处理的直方图
img1=cv2.equalizeHist(img)
#绘制均衡化处理后的直方图
plt.hist(img1.ravel(),256)

7.subplot函数的使用

#subplot函数的使用:subplot(行数,列数,窗口序号)
#当三个参数都小于10,就可以去掉逗号,例如subplot(2,3,4)=subplot(234)

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

img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#不进行直方图均衡化的直方图的绘制
plt.subplot(1,2,1)
plt.hist(img.ravel(),256)#进行一行两列第一个窗口的绘制

#进行直方图均衡化的直方图绘制
img1=cv2.equalizeHist(img)
plt.subplot(122)
plt.hist(img1.ravel(),256)#进行一行两列第二个窗口的绘制

8.matplotlib.pyplot.imshow函数使用

#imshow(要绘制图像,cmap)
#cmap:默认情况下是RGB图像;
# 如果是灰度图像,就用plt.cm.gray
#如果是通过opencv读取的图像,默认是BGR颜色空间,但是matplotlib.pyplot.imshow()默认的颜色空间是RGB,所以要进行转换颜色空间


import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png")#原始图像是BGR颜色空间的图像
img_gray=cv2.cvtColor(img,cv2.COLOR_BGRA2GRAY)#将原始图片转换成灰度图片

#在下列的图片中,只有第四个图像的显示结果是正确的

#两行两列的第一个窗口的显示:使用默认通道顺序显示img--显示结果是错的
plt.subplot(2,2,1)
plt.imshow(img)
plt.axis('off')#坐标轴显示关闭

#两行两列的第二个窗口显示:使用灰度显示img--显示结果是错的
plt.subplot(222)
plt.imshow(img,plt.cm.gray)
plt.axis('off')#坐标轴显示关闭

#两行两列第三个窗口显示:使用默认通道顺序显示img_gray--显示结果是错的
plt.subplot(223)
plt.imshow(img_gray)
plt.axis('off')#坐标轴显示关闭

#两行两列第四个窗口显示:使用灰度显示img_gray--显示结果是对的
plt.subplot(224)
plt.imshow(img_gray,plt.cm.gray)
plt.axis('off')#坐标轴显示关闭


#彩色图像的正确展示
b,g,r=cv2.split(img)
img1=cv2.merge([r,g,b])
plt.suplot(121)
plt.imshow(img1)
plt.axis('off')

plt.subplot(1,2,2)
plt.imshow(img_gray,plt.cm.gray)
plt.axis('off')

9.直方图均衡化的对比

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#两行两列的第一个窗口:原始的灰度图像的显示
plt.subplot(2,2,1)
plt.imshow(img,plt.cm.gray)#使用灰度图像显示的方式
plt.axis('off')#关闭图像的坐标轴

#两行两列的第二个窗口:经过直方图均衡化的图像的显示
img1=cv2.equalizeHist(img)#对原始图像进行直方图均衡化
plt.subplot(2,2,2)
plt.imshow(img1,plt.cm.gray)#使用灰度图像显示的方式
plt.axis('off')#关闭图像的坐标轴

#两行两列的第三个窗口:没有经过均衡化的直方图
plt.subplot(2,2,3)
plt.hist(img.ravel(),256)

#两行两列的第四个窗口:经过均衡化的直方图
plt.subplot(224)
plt.hist(img1.ravel(),256)

三、傅里叶变换

1.numpy实现傅立叶变换

#numpy实现傅立叶变换函数
#numpy.fft.fft2:实现傅立叶变换,返回的是一个复数数组
#numpy.fft.fftshift:将零频率分量移到频谱中心
#20*np.log(np.abs(fshift)):设置频谱的范围,映射到0-255

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#实现傅立叶变换,获得低频和高频信息
f=np.fft.fft2(img)
#将低频信息移到频谱中心
fshift=np.fft.fftshift(f)
#设置频谱的范围
result=20*np.log(np.abs(fshift))

#设置一行两列的第一个窗口:
plt.subplot(1,2,1)
plt.imshow(img,plt.cm.gray)#用灰度通道的形式展现原始的灰度图片
plt.title("original")#设置第一个窗口的名字是original
plt.axis('off')#去除图像的坐标轴

#设置一行两列的第二个窗口:
plt.subplot(1,2,2)
plt.imshow(result,plt.cm.gray)#用灰度通道的形式展现经过傅立叶变换的图片
plt.title("result")#设置第一个窗口的名字是result
plt.axis('off')#去除图像的坐标轴

plt.show()

2.numpy实现逆傅立叶变换

#傅立叶变换的过程是可逆的,图像经过傅立叶变换和逆傅立叶变换后,能够恢复到原始图像
#可以在频域对图像进行处理,在频域的处理会反映在变换图像上

#numpy.fft.ifft2:实现逆傅立叶变换
#numpy.fft.ifftshift:fftshift的逆函数:将低频由频谱中心移到零频位置上
#iimg=np.abs:设置值的范围,调整到【0-255】

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#傅立叶变换
f=np.fft.fft2(img)#实现傅立叶变换,得到低频和高频的信息
fshift=np.fft.fftshift(f)#将零频律分量移到频谱中心
result1=20*np.log(np.abs(fshift))#傅立叶变换的结果

#逆傅立叶变换
i1=np.fft.ifftshift(fshift)#将低频由频谱中心移到零频位置上
i2=np.fft.ifft2(i1)#实现逆傅立叶变换
result2=np.abs(i2)#设置值的范围,调整到【0-255】

plt.subplot(1,3,1)
plt.imshow(img,plt.cm.gray)
plt.title("original")
plt.axis('off')

plt.subplot(1,3,2)
plt.imshow(result1,plt.cm.gray)
plt.title("result1")
plt.axis('off')

plt.subplot(1,3,3)
plt.imshow(result2,plt.cm.gray)
plt.title("result2")
plt.axis('off')

plt.show()

3.高通滤波演示

细节会丢失,增强边缘尖锐信息

#低频:对应图像内变化缓慢的灰度分量
#例如:在一幅大草原的图像中,低频表示广袤的颜色趋向于一致的草原
#高频:对应图像内变化越来越快的灰度分量,由灰度的尖锐过度造成的
#例如:在一幅大草原的图像中,其中狮子的边缘等信息

#滤波:接受和拒绝一定频率的分量
#通过低频的滤波器是低通滤波器:低频通过,高频衰减,图像将会变模糊(边缘信息丢失,细节保留)
#通过高频的滤波器是高通滤波器:高频通过,低频衰减,图像增强了尖锐细节,但是图像的对比度降低(边缘信息保留,细节丢失)

#先对图像进行傅立叶变换,再对图像的低频和高频进行处理以达到特殊目的,再进行逆傅立叶变换返回图像域
#特殊目的:图像增强、图像去噪、边缘检测、特征提取、压缩、加密等

import cv2
import numpy as np
import matplotlip as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#傅立叶变换
f=np.fft.fft2(img)#进行傅立叶变换,得到高频和低频信息
fshift=np.fft.fftshift(f)#将零频区域移到频谱中心

#高通滤波器,去掉低频,低频已经被移到了中心
rows,cols=img.shape
crow,ccol=int(rows/2),int(cols/2)
fshift[crow-30:crow+30,ccol-30:ccol+30]=0

#逆傅立叶变换
i1=np.fft.ifftshift(fshift)#将频谱中心移到原处
i2=np.fft.ifft(i1)#逆傅立叶变换
result=np.abs(i2)#设置值的范围,调整到【0-255】

plt.subplot(1,2,1)
plt.imshow(img,plt.cm.gray)
plt.title("original")
plt.axis('off')
plt.subplot(1,2,2)
plt.imshow(result,plt.cm.gray)
plt.title("result")
plt.axis('off')
plt.show()

4.opencv实现傅立叶变换

#cv2.dft(scr,转换标识)
#返回结果是双通道的,第一个是结果的实数部分,第二个是结果的虚数部分
#scr:np.float32(原始图像)
#转换标识:cv2.DFT_COMPLEX_OUTPUT,输出一个复数阵列

#numpy.fft.fftshift:将零频律分量移动到频谱中心
#结果图像=20*np.log(cv2.magnitude(实部部分,虚部部分))

import cv2
import numpy as np
import matplotlip as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#傅立叶变换
f=cv2.dft(np.float32(img),cv2.DFT_COMPLEX_OUTPUT)#傅立叶变换
fshift=np.fft.fftshift(f)#将零频律分量移动到频谱中心
result=20*np.log(cv2.magnitude(fshift[:,:,0],fshift[:,:,1]))

plt.subplot(121)
plt.imshow(img,plt.cm.gray)
plt.title("orginal")
plt.axis('off')
plt.subplot(122)
plt.imshow(result,plt.cm.gray)
plt.title("result")
plt.axis('off')

plt.show()

5.opencv实现逆傅立叶变换

import cv2
import numpy as np
import matplotlip.pyplot as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#傅立叶变换
f=cv2.dft(np.float32(img),cv2.DFT_COMPLEX_OUTPUT)#傅立叶变换
fshift=np.fft.fftshift(f)#将零频移动到频谱中心
result1=np.log(cv2.magnitude(fshift[:,:,0],fshift[:,:,1]))#得到傅立叶变换的结果

ishift=np.fft.ifftshift(fshift)#将低频由频谱中心移到零频位置上
i=cv2.idft(ishift)#逆傅立叶变换
result2=cv2.magnitude(i[:,:,0],i[:,:,1])#得到逆傅立叶变换结果

plt.subplot(1,3,1)
plt.imshow(img,plt.cm.gray)
plt.title("original")
plt.axis('off')

plt.subplot(1,3,2)
plt.imshow(result1,plt.cm.gray)
plt.title("result1")
plt.axis('off')

plt.subplot(1,3,3)
plt.imshow(result2,plt.cm.gray)
plt.title("result2")
plt.axis('off')

plt.show()

6.低通滤波示例 

 

import cv2
import numpy as np
import matplotlip as plt
img=cv2.imread("/Users/macbook/Desktop/face.png",cv2.IMREAD_GRAYSCALE)

#傅立叶变换
f=cv2.dft(np.float32(img),cv2.DFT_COMPLEX_OUTPUT)#傅立叶变换
fshift=np.fft.fftshift(f)#将零频移动到频谱中心
result1=np.log(cv2.magnitude(fshift[:,:,0],fshift[:,:,1]))#傅立叶变换结果图像

#低通滤波器
rows,cols=img.shape
mask=np.zeros((rows,cols,2),np.uint8)
crows,ccols=int(rows/2),int(cols/2)
mask[crows-30:crows+30,ccols-30:ccols+30]=1
fshift1=fshift*mask#滤波

#逆傅立叶变换
i1=np.fft.ifftshift(fshift1)#将频谱中心移到原处
i2=cv2.idfs(i1)#逆傅立叶变换
result2=cv2.magnitude(i2[:,:,0],i2[:,:,1])#得到逆傅立叶变换结果

plt.subplot(1,2,1)
plt.imshow(img,plt.cm.gray)
plt.title("original")
plt.axis('off')
plt.subplot(1,2,2)
plt.imshow(result2,plt.cm.gray)
plt.title("result2")
plt.axis('off')
plt.show()

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值