opencv

opencv

读取图片

image = cv2.imread('image.jpg')     #原BGR格式
plt.imshow(image)					#以RGB方式显示
plt.axis('off')   					#不显示坐标轴RGB

image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)		#设置以RGB格式显示  (查看并改变通道方式)
plt.imshow(image)
plt.axis('off')   					#不显示坐标轴

cv2.imwrite("new_image2.jpg",image) #保存图片 最终以RGB保存,所以不能用cvtColor(改变了通道方式)

取某一像素

(b, g, r) = image[0,0]			# image.shape (1440, 1080, 3) 取[0,0]的像素 对应有3个值

image[0,0] = (0, 0, 255)		#赋值

取左上角图片

(h,w) = image.shape[:2]			# h image.shape[0] , w image.shape[1]    
cX, cY = (w//2,h//2)			
tl = image[0:cY,0:cX]			#取左上角图片(1/4)
plt.imshow(tl)
plt.axis('off')

image[0:cY,0:cX] = (0, 0, 255)  #左上角图片变蓝

显示图片

def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

读取图片

def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

平移 np.float32

image = imread('image.jpg')
(h,w) = image.shape[:2]
M = np.float32([[1,0,500],[0,1,500]])	#向右 向下
shifted = cv2.warpAffine(image, M, (w,h))
show(shifted)

旋转 cv2.getRotationMatrix2D

image = imread('image.jpg')
(h,w) = image.shape[:2]
(cX,cY) = (w/2,h/2)
M = cv2.getRotationMatrix2D((cX,cY), 45, 1.0)	
# (cX,cY)-旋转中心点,45-逆时针旋转45度,1.0-缩放
#M = cv2.getRotationMatrix2D((cX+500,cY+500), 45, 1.0)		#向左 向下

image = cv2.warpAffine(image, M, (w,h))

调整大小

width = 150
high = 150 
#high = int(image.shape[0]*width/image.shape[1])	等比例转换

image = cv2.resize(image, (width, high))
#image = cv2.resize(image, (width, high), interpolation=cv2.INTER_NEAREST)	#算法
show(image)
print(image.shape)

人脸检测

image = imread('face.png')
# 级联分类器
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flags=cv2.CASCADE_SCALE_IMAGE)

for (x,y,w,h) in rects:
    # 画矩形框
    cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
    
show(image)

人脸检测函数

def facedetect(image):
    image = imread(image)
    # 级联分类器
    detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flags=cv2.CASCADE_SCALE_IMAGE)

    for (x,y,w,h) in rects:
        # 画矩形框
        cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)

    show(image)

画图

image = np.zeros((300,300,3),dtype='uint8')		#黑色图片

green = (0,255,0)
cv2.line(image, (0,0), (300,300), green)		#绿线

blue = (0,0,255)
cv2.line(image, (300,0), (150,150), blue, 5)	#线宽 5

#三角
red = (255,0,0)
cv2.rectangle(image, (10,10), (60,60), red, 2)	#矩形
cv2.rectangle(image, (50,200), (220,280), green, -1)	#填充

#画⚪
image = np.zeros((300,300,3),dtype='uint8')
(cX, cY) = image.shape[1]//2, image.shape[0]//2
white = (255,255,255)
for r in range(0,151,15):
    cv2.circle(image, (cX,cY), r,(255,255,0), 2)
show(image)

#画随机⚪
image = np.zeros((300,300,3),dtype='uint8')
for i in range(10):
    # 半径取值
    radius = np.random.randint(5,200)
    # 颜色取值
    color = np.random.randint(0,255,size=(3,)).tolist()
    # 圆心取值
    pt = np.random.randint(0,300,size=(2,))
    # 画图
    cv2.circle(image, tuple(pt), radius, color, -1)
show(image)

翻转

image = cv2.flip(image,1)		#1代表水平	0代表垂直	-1水平+垂直

加法

# 图像加法
print(cv2.add(np.uint8([200]),np.uint8([100])))		#[[255]]	最大255
# 普通加法
print(np.uint8([200])+np.uint8([100]))				#255+1=0    [44]

减法

# 图像减法
print(cv2.subtract(np.uint8([50]),np.uint8([100])))		#[[0]]
# 普通减法
print(np.uint8([50])-np.uint8([100]))    				#50-1=255     [206]

变亮

image = imread('test.jpg')
# 生成跟图片形状相同的并且全为100的数据
M = np.ones(image.shape, dtype='uint8')*100
# 所有的像素加100
image = cv2.add(image, M)
#image = cv2.subtract(image, M)		#变暗
show(image)

按位

rectangle = np.zeros((300,300,3),dtype='uint8')
white = (255,255,255)
cv2.rectangle(rectangle, (25,25), (275,275), white, -1)		#三角

circle = np.zeros((300,300,3), dtype='uint8')
cv2.circle(circle, (150,150), 150, white, -1)		#⚪

# AND,与操作,有黑就变黑
image = cv2.bitwise_and(rectangle, circle)

# OR,或操作,有白就变白
image = cv2.bitwise_or(rectangle, circle)

# XOR,异或操作,黑白变白,黑黑和白白变黑		相同变黑
image = cv2.bitwise_xor(rectangle, circle)

# NOT, 非操作,颜色取反
image = cv2.bitwise_not(circle)

遮挡

mask = np.zeros(image.shape,dtype='uint8')
white = (255,255,255)
cv2.rectangle(mask, (50,50), (250,350), white, -1)		#相框

masked = cv2.bitwise_and(image, mask)

mask = np.zeros(image.shape,dtype='uint8')
white = (255,255,255)
cv2.circle(mask, (150,100), 80, white, -1)			#⚪

切分,合并

(R, G, B) = cv2.split(image)

merged = cv2.merge([R,G,B])

图像金字塔

同一图像的不同分辨率的子图集合

 cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔 
 cv2.pyrDown(image)
 cv2.pyrUp(image)

拉普拉斯金字塔: 𝐿𝑖=𝐺𝑖−𝑝𝑦𝑟𝑈𝑝(𝐺𝑖+1)

down_image1 = cv2.pyrDown(image)
down_image2 = cv2.pyrDown(down_image1)
up_image = cv2.pyrUp(down_image2)
laplacian = down_image1-up_image

腐蚀 黑色的部分变得更加大

# 矩形
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))			#morph 变形
# 椭圆
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
# 十字形
kernel3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5))
for i in range(3):
    erosion = cv2.erode(image, kernel3, iterations=i+1)  #iterations腐蚀次数
    show(erosion)                                        #黑色的部分变得更加大

膨胀 白色的部分变得更加大

for i in range(3):
    dilation = cv2.dilate(image, kernel1, iterations=i+1)		#白色的部分变得更加大
    show(dilation)

开运算 去除白点

先腐蚀后膨胀

image2 = imread('image2.jpg')				
# 去除白点
opening = cv2.morphologyEx(image2, cv2.MORPH_OPEN, kernel1)

闭运算 去除黑点

先膨胀后腐蚀

# 去除黑点
closing = cv2.morphologyEx(image2, cv2.MORPH_CLOSE, kernel1)

先开后闭

opening = cv2.morphologyEx(image2, cv2.MORPH_OPEN, kernel1)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel1)

梯度 物体的轮廓

得到物体的轮廓

gradient = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel1)		#dilation - erosion

顶帽/白帽 去除掉的白色部分

被去除掉的白色部分

tophat = cv2.morphologyEx(image2, cv2.MORPH_TOPHAT, kernel1)#      	 	#src - opening

黑帽 去除掉的黑色部分

被去除掉的黑色部分

blackhat = cv2.morphologyEx(image2, cv2.MORPH_BLACKHAT, kernel1)		#closing - src

图像平滑

# 平均平滑
blur = cv2.blur(image, kernel)

blur = cv2.GaussianBlur(image, kernel, 0)	#高斯模糊		0 标准差	方框中心的值最大
blur = cv2.medianBlur(image, kernel)		#中值模糊	卷积框对应像素的中值来替代中心像素的值。

#双边滤波		能在保持边界清晰的情况下有效的去除噪音
blur = cv2.bilateralFilter(image, diameter,sigmaColor,sigmaSpace)

灰度

image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
cv2.imshow('original',image)
cv2.imshow('gray',gray)			#后面要加gray 

cv2.waitKey(0) 			
# waitKey的功能是等待一定的时间,如果等待时间内有按键操作就继续执行后面的语句,如果没有按键就在等待时间到后继续执行后面的语句。时间以ms为单位。waitKey参数为0的时候窗口不会自动关闭,无限等待按键
cv2.destroyAllWindows()

二值化

把图片传换成只有white和black这两种颜色

1

plt.imshow(gray,'gray')			#前面为数据	后面为方式

cv2.imshow('gray2',gray2)		#前面为标题	展示出来

2

ret1,thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)		#阈值	最大值
ret2,thresh2 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
ret3,thresh3 = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC)
ret4,thresh4 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO)
ret5,thresh5 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO_INV)

plt.imshow(thresh1,'gray')

自动选择阈值

image = imread('image/opencv_logo.png')
ret1,thresh1 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
plt.imshow(thresh1,'gray')
plt.axis('off')
plt.show()

自适应阈值

image = imread('image/license_plate.png')
image = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
# 平均值阈值
th2 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,3)
# 高斯阈值
th3 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,3)
#11 邻域大小(用来计算阈值的区域大小)。	阈值就等于平均值或者加权平均值减去这个常数 3
plt.imshow(thresh2,'gray')
plt.axis('off')
plt.show()

梯度

def gradient(image):
    image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # cv2.CV_64F输出图像的深度(数据类型),64位float类型,因为梯度可能是正也可能是负
    laplacian = cv2.Laplacian(image, cv2.CV_64F)
    # 1, 0表示在x方向求一阶导数,最大可以求2阶导数
    sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
    # 0, 1表示在y方向求一阶导数,最大可以求2阶导数
    sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
    titles = ['Original', 'Laplacian', 'SobelX', 'SobelY']
    images = [image,laplacian,sobelx,sobely]
    plt.figure(figsize=(10,5))
    for i in range(4):
        plt.subplot(2,2,i+1)
        plt.imshow(images[i],'gray')
        plt.title(titles[i])
        plt.axis('off')
    plt.show()

Canny边缘检测

def edge_detection(image,minVal=100,maxVal=200):		#阈值(100~200)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    edges = cv2.Canny(image,minVal,maxVal)
    plt.imshow(edges,'gray') 
    plt.axis('off')
    plt.show()
# 自动确定阈值的一种方法
def auto_canny(image, sigma=0.33):
    v = np.median(image)
    lower = int(max(0, (1.0-sigma) * v))
    upper = int(min(255, (1.0+sigma) * v))
    edged = cv2.Canny(image, lower, upper)
    print(lower,upper)
    return edged

摄像头读取

import numpy as np
import cv2
# 从摄像头获取图像数据
cap = cv2.VideoCapture(0)

while(True):
    # ret 读取成功True或失败False 
    # frame读取到的图像的内容
    # 读取一帧数据
    ret,frame = cap.read()
    # 变为灰度图
#     gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    cv2.imshow('frame',frame)
    # waitKey功能是不断刷新图像,单位ms,返回值是当前键盘按键值
    # ord返回对应的ASCII数值
    if cv2.waitKey(1)& 0xFF == ord('q'):      # 0xFF 把返回值限制在在0和255之间
        break
cap.release()
cv2.destroyAllWindows()
# 从文件读取视频内容
cap = cv2.VideoCapture('videos/cats.mp4')

# 视频每秒传输帧数
fps = cap.get(cv2.CAP_PROP_FPS)
# 视频图像的宽度
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 视频图像的长度
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

while(True):
    # ret 读取成功True或失败False
    # frame读取到的图像的内容
    # 读取一帧数据
    ret,frame = cap.read()
    if ret!=True:     		#播放完关闭
        break
    cv2.imshow('frame',frame)
    # waitKey功能是不断刷新图像,单位ms,返回值是当前键盘按键值
    # ord返回对应的ASCII数值
    if cv2.waitKey(25) & 0xff == ord('q'):			#25	调整合适速度
        break
cap.release()
cv2.destroyAllWindows()

视频写入

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('videos/output2.avi',fourcc,fps,(frame_width,frame_height))

while(True):
    ret, frame = cap.read()
    if ret==True:
        # 水平翻转
        frame = cv2.flip(frame,1)
        out.write(frame)
#         cv2.imshow('frame',frame)
#         if cv2.waitKey(25) & 0xff == ord('q'):
#             break
    else:
        break
out.release()
cap.release()
cv2.destroyAllWindows()

人脸检测

Haar特征+Adaboost级联分类器

色矩形所有像素值的和减去白色矩形所有像素值的和

# 级联分类器		人脸检测的模型		6061个特征	38个阶段
detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10,10), flags=cv2.CASCADE_SCALE_IMAGE)

for (x,y,w,h) in rects:			#检测多少个脸,画多少个框
    # 画矩形框
    cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
show(image) 

函数

def facedetect(image):
    image = imread(image)
    # 级联分类器
    detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
    rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10,10), flags=cv2.CASCADE_SCALE_IMAGE)

    for (x,y,w,h) in rects:
        # 画矩形框
        cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)

    show(image)
文件操作

创建文件

output2='predict_faces/anglababy2'
os.makedirs(output2)
for files in os.listdir('faces/anglababy'):			#查看当前路径下的所有文件
    print(files)
采集人脸样本
# 人脸检测并保存人脸
def facedetect(image, output):
    # 获取文件名
    name = os.path.basename(image)
    # 读入图片
    image = cv2.imread(image)
    # 变成灰度图
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 级联分类器,检测人脸
    detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
    rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=3, minSize=(20, 20), flags=cv2.CASCADE_SCALE_IMAGE)
    # 循环每个人脸
    for (x,y,w,h) in rects:
        # 截取人脸,并且都转化为200*200的固定大小
        f = cv2.resize(image[y:y+h, x:x+w], (200,200))
        # 写入指定路径
        cv2.imwrite(os.path.join(output, name), f)
# 检测并截取人脸
def predict_face(path, output):
    # 如果该文件夹不存在则创建文件夹
    if not os.path.exists(output):
        os.makedirs(output)
    # 循环每个人物的文件夹下的图片
    for files in os.listdir(path):
        # 检测是不是文件夹
        if os.path.isdir(os.path.join(path, files)):      #path下面的各个文件路径
            # 定义截取到的人脸的输出路径
            output2 = os.path.join(output, files)         #output下面的各个文件路径
            # 如果该文件夹不存在则创建文件夹
            if not os.path.exists(output2):				  #创建
                os.makedirs(output2)
            # 人物文件夹的完整路径
            files = os.path.join(path, files)
            # 循环每个人的每张照片
            for file in os.listdir(files):
                # 照片完整路径
                file = os.path.join(files, file)
                # 检测人脸并保存
                facedetect(file, output2)
生成label文件
for root, dirs, files in os.walk('predict_faces'):
    print('r',root)			#包括自己的所有文件夹	str		
    print('d',dirs)			#文件夹			 list
    print('f',files)		#文件				  list
# 生成label文件
def get_label(path):
    fh = open("label.txt", 'w')
    # 表示人脸label
    label = 0
    for root, dirs, files in os.walk(path):
        # 循环每个文件夹
        for subdir in dirs:			#root中所有文件
            # 文件夹完整路径
            subdir_path = os.path.join(root,subdir)
            # 循环每个人物文件夹下面每张照片
            for file in os.listdir(subdir_path):
                # 照片完整路径
                filepath = os.path.join(subdir_path, file)
                # 判断文件类型是不是图片类型
                imgType = imghdr.what(filepath)
                if imgType == 'jpeg' or imgType == 'png':
                    # 保存图片路径
                    fh.write(filepath);
                    fh.write(";")
                    # 标签
                    fh.write(str(label))
                    fh.write("\n")
            # 每个人的标签不一样,从0开始计数
            label = label + 1            
    fh.close()
训练自己的数据模型
# 保存图片数据
images = []
# 保存标签
labels = []
# 打开文件
fh = open("label.txt")
# 循环每一行
for line in fh:
    # 以;切分字符串
    arr = line.split(";")
    # 第0部分为图片路径,读取文件
    img = cv2.imread(arr[0],0)
    # 保存图片数据
    images.append(img)
    # 保存对应的标签数据
    labels.append(int(arr[1]))
    
# 安装opencv扩展包
# pip install opencv-contrib-python
# 定义人脸识别模型
model = cv2.face.EigenFaceRecognizer_create()
# model = cv2.face.FisherFaceRecognizer_create()
# model = cv2.face.LBPHFaceRecognizer_create()
# 训练模型
model.train(np.array(images), np.array(labels))
# 保存模型
model.save("predict_face_XiaoMing_AB.xml")
人脸识别
# 定义人物名字
name= ['ab','xiaoming']
# 定义人脸识别模型
model = cv2.face.EigenFaceRecognizer_create()
# 载入训练好的模型
model.read('predict_face_XiaoMing_AB.xml')

# 读入测试图片来做测试
for file in os.listdir('test'):
    file = os.path.join('test', file)
    # 判断文件类型
    imgType = imghdr.what(file)
    if imgType == 'jpeg' or imgType == 'png':
        # 读入图片
        image = imread(file)
        # 变为灰度图
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        # 级联分类器
        detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
        rects = detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(20, 20), flags=cv2.CASCADE_SCALE_IMAGE)
        # 循环每个人脸
        for (x,y,w,h) in rects:
            # 画矩形框
            cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
            # 人脸识别
            face = cv2.resize(gray[y:y+h,x:x+w], (200,200))
            # 预测人物
            params = model.predict(face)
            # 写上人物名字
            cv2.putText(image,name[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
        show(image)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值