← 返回首页
Python cv2(Opencv) 图像基本操作
发表时间:2024-03-25 12:39:15
Python cv2(Opencv) 图像基本操作

Python cv2(Opencv) 图像基本操作

1.open-cv简介

OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效,由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。本小节主要讲解Python 中使用cv2(Opencv) 进行图像的基本操作的方法及示例代码。

2.OpenCV常见操作

1).安装opencv

#安装numpy
pip install numpy
#安装opencv-python
pip install opencv-python
#安装opencv-contrib-python
pip install opencv-contrib-python

#推荐指定清华源进行安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python

2).使用OpenCV读取图像数据

使用cv2.imread方法读取图像,常见参数:

# opencv读取的格式是BGR
import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('./imgs/xinhua.jpg')
#print(img)
print(img.shape)
# 图像的显示,也可以创建多个窗口
cv2.imshow('color-image', img)
#cv2.waitKey(0)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()

img = cv2.imread('./imgs/xinhua.jpg', cv2.IMREAD_GRAYSCALE)
#print(img)
print(img.shape)
# 图像的显示,也可以创建多个窗口
cv2.imshow('gray-image', img)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(10000)
cv2.destroyAllWindows()
# 保存
cv2.imwrite('./dest/mypic.jpg', img)
print(type(img))

#size表示数组元素的个数,而非字节个数。
print(img.size)
print(img.dtype)

cv2.imread 默认情况下可能不支持包含非ASCII字符(如汉字)的文件路径,因为 OpenCV 底层使用的是 C++ 的 fopen 函数,它通常不支持 UTF-8 或 Unicode 文件名。这会导致当文件路径中含有汉字时无法正常读取文件。

一个通常的解决办法是先将图片读入一个字节流(bytes),然后使用 OpenCV 的 imdecode 函数从内存中解码图像即将字节流解码为图像数组。

参考代码如下:

import cv2
import numpy as np
file_path='./imgs/刘德华001.png'
with open(file_path, 'rb') as f:
  image_data = f.read()

image = cv2.imdecode(np.frombuffer(image_data, np.uint8), cv2.IMREAD_COLOR)
if image is not None:
  cv2.imshow('image', image)
  cv2.waitKey(0)
else:
  print('Failed to load image.')

OpenCV读取图像的函数封装。

def show_img(file_name):
    #字符流转换字节流,这样可以读取中文文件名
    with open(file_name, 'rb') as f:
        image_data = f.read()
    img = cv2.imdecode(np.frombuffer(image_data, np.uint8), cv2.IMREAD_COLOR)
    #print(img.shape)
    # 获取图片的宽度和高度
    height, width = img.shape[:2]
    print(f"图片尺寸=>宽度:{width},高度:{height}")
    #调整尺寸缩放功能,可选
    resized_img = cv2.resize(img, (int(width/2), int(height/2)), interpolation=cv2.INTER_AREA)
    # 图像的显示,也可以创建多个窗口
    #cv2.imshow('color-image', img)
    cv2.imshow('color-image', resized_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

3).使用cv2(OpenCV)读取视频数据

使用cv2.VideoCapture()可以捕获摄像头,用数字来控制不同的设备,例如,0,1。视频文件只需指定好路径即可。

# opencv读取的格式是BGR
import cv2
import matplotlib.pyplot as plt
import numpy as np

#创建VideoCapture对象
vc = cv2.VideoCapture('./video/test_track.mp4')
# 检查是否打开正确
if vc.isOpened():
    open, frame = vc.read()
else:
    open = False

while open:
    ret, frame = vc.read()
    if frame is None:
        break
    if ret == True:
        #把视频转换为灰度
        #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        #cv2.imshow('result', gray)
        color = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        cv2.imshow('result', color)

        #按ESC键退出
        if cv2.waitKey(100) & 0xFF == 27:
            break

#释放VideoCapture对象      
vc.release()
#关闭所有OpenCV窗口
cv2.destroyAllWindows()

通常我们习惯点击视频窗口的关闭按钮立刻关闭视频,参考代码如下:

# opencv读取的格式是BGR
import cv2
import matplotlib.pyplot as plt
import numpy as np

#创建VideoCapture对象
vc = cv2.VideoCapture('./video/test_track.mp4')
# 检查是否打开正确
if vc.isOpened():
    open, frame = vc.read()
else:
    open = False

while open:
    ret, frame = vc.read()
    if frame is None:
        break
    if ret == True:
        #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        #cv2.imshow('result', gray)
        color = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        cv2.imshow('result', color)

        #waitKey() 函数的功能是不断刷新图像 , 频率时间为delay , 单位为ms
        cv2.waitKey(100)
        if cv2.getWindowProperty('result', cv2.WND_PROP_VISIBLE) < 1:
            break
vc.release()
cv2.destroyAllWindows()

OpenCV播放视频的函数封装。

#opencv播放视频
def play_video(file_name):
    # 创建VideoCapture对象
    vc = cv2.VideoCapture(file_name)
    # 检查是否打开正确
    if vc.isOpened():
        open, frame = vc.read()
    else:
        open = False
    while open:
        ret, frame = vc.read()
        if frame is None:
            break
        if ret == True:
            height, width = frame.shape[:2]
            #调整视频尺寸可选
            resized_frame = cv2.resize(frame, (int(width/2), int(height/2)), interpolation=cv2.INTER_AREA)
            cv2.imshow('result',resized_frame)
            #cv2.imshow('result', frame)
            cv2.waitKey(20)
            if cv2.getWindowProperty('result', cv2.WND_PROP_VISIBLE) < 1:
                break
    # 释放VideoCapture对象
    vc.release()
    # 关闭所有OpenCV窗口
    cv2.destroyAllWindows()

4).使用cv2(OpenCV)截取部分图像数据

#opencv读取的格式是BGR
import cv2
import matplotlib.pyplot as plt
import numpy as np

img=cv2.imread('./imgs/xinhua.jpg')
print(img)
#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
cv2.waitKey(0)

part=img[40:180,240:420]
cv2.imshow("part",part)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()

5).边缘检测

import cv2
import numpy as np
img = cv2.imread('./images/dance_girl_001.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src', img)
#canny 1 gray 2 高斯 3 canny
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgG = cv2.GaussianBlur(gray, (3, 3), 0)
dst = cv2.Canny(img, 50, 50) #1 data 2 th 图片卷积->th
cv2.imshow('dst', dst)
cv2.waitKey(0)

另一种算法:

import cv2
import numpy as np
import math
img = cv2.imread('./images/dance_girl_001.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src', img)
# sobel 1 算子模板 2 图片卷积 3 阈值判决
# [1 2 3 4] [a b c d] a*1+b*2+c*3+d*4 = dst
# sqrt(a*a+b*b) = f>th
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 1), np.uint8)
for i in range(0, height-2):
    for j in range(0, width-2):
        gy = gray[i,j]*1+gray[i,j+1]*2+gray[i,j+2]*1-gray[i+2,j]*1-gray[i+2,j+1]*2-gray[i+2,j+2]*1
        gx = gray[i,j]*1+gray[i+1,j]*2+gray[i+2,j]*1-gray[i,j+2]*1-gray[i+1,j+2]*2-gray[i+2,j+2]*1
        grad = math.sqrt(gx*gx+gy*gy)
        if grad > 50:
            dst[i, j] = 255
        else:
            dst[i, j] = 0
cv2.imshow('dst', dst)
cv2.waitKey(0)