本文主要参考自 OpenCV官方文档
访问、修改像素值
import cv2
img = cv2.imread('../../Resources/messi15.jpg')
px = img[100, 100]
print(px)
# 仅访问单一通道像素值
blue = img[100, 100, 0]
print(blue)
# 修改像素值
img[100, 100] = [255, 255, 255]
print(img[100, 100])
# 更好的像素访问和编辑方法,返回标量
# 访问 RED 值
print(img.item(10, 10, 2))
# 修改RED值
img.itemset((10, 10, 2), 100)
print(img.item(10, 10, 2))
访问图像属性
# 图像形状
print(img.shape)
# 图像像素值总数
print(img.size)
# 图像数据类型
print(img.dtype)
图像感兴趣区域ROI
使用Numpy索引获得ROI,选择球并将其复制到图像中的另一个区域:
import cv2
img = cv2.imread('../../Resources/messi15.jpg')
ball = img[280:340, 330:390]
img[273:333, 100:160] = ball
cv2.imshow('messi', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
为图像设置边框(了解即可)
如果要在图像周围创建边框(如相框),则可以使用 cv.copyMakeBorder() 。
其参数如下:
src
:输入图像
top
,bottom
,left
,right
:边界宽度(以相应方向上的像素数为单位)
borderType
:定义要添加哪种边框的标志。它可以是以下类型:
cv.BORDER_CONSTANT
:添加恒定的彩色边框。该值应作为下一个参数给出。
cv.BORDER_REFLECT
:边框将是边框元素的镜像,如下所示: fedcba | abcdefgh | hgfedcb
cv.BORDER_REFLECT_101
或 cv.BORDER_DEFAULT
与上述相同,但略有变化,例如: gfedcb | abcdefgh | gfedcba
cv.BORDER_REPLICATE
:最后一个元素被复制,像这样: aaaaaa | abcdefgh | hhhhhhh
cv.BORDER_WRAP
:难以解释,它看起来像这样: cdefgh | abcdefgh | abcdefg
value
:边框的颜色,如果边框类型为 cv.BORDER_CONSTANT
import cv2
from matplotlib import pyplot as plt
BLUE = [255, 0, 0]
img1 = cv2.imread('../../Resources/opencv-logo.jpg')
replicate = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=BLUE)
print(img1, reflect)
plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
import cv2
img1 = cv2.imread('../../Resources/3D-Matplotlib.png')
img2 = cv2.imread('../../Resources/mainsvmimage.png')
add = img1 + img2 # 模运算,250+10 = 260 % 256 = 4
cv_add = cv2.add(img1, img2) # 像素点值相加,所以图片变白,50+10 = 260 => 255
cv2.imshow('add', add)
cv2.imshow('cv_add', cv_add)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
img1 = cv2.imread('./Image/3D-Matplotlib.png')
img2 = cv2.imread('./Image/mainsvmimage.png')
weighted = cv2.addWeighted(img1, 0.6, img2, 0.4, 0) # 设置权重进行叠加
cv2.imshow('weighted', weighted)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下cv2.bitwise_or(img1, img2)
cv2.bitwise_and(img1, img2)
cv2.bitwise_not(img1)
cv2.bitwise_xor(img1, img1)
,cv2.bitwise_xor(img1, img2)
img1 = cv2.imread('../../Resources/3D-Matplotlib.png')
img2 = cv2.imread('../../Resources/mainlogo.png')
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]
img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2_gray, 220, 255, cv2.THRESH_BINARY_INV)
mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
# cv2.imshow('img_', img2_gray)
# cv2.imshow('img_1', mask)
# cv2.imshow('img_2', mask_inv)
# cv2.imshow('img_3', img1_bg)
# cv2.imshow('img_4', img2_fg)
# cv2.imshow('mask', mask)
cv2.imshow('new_img', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下import cv2
import random
import numpy as np
import pandas as pd
from PIL import Image, ImageDraw, ImageFont
import time
# 颜色
def rand_color():
font_r = random.randint(128, 255)
font_g = random.randint(128, 255)
font_b = random.randint(128, 255)
return font_r, font_g, font_b
# 矩形坐标读取
def rectangle_point(index):
data = pd.read_table("coordinate.txt", sep=",", header=None)
point_x, point_y = [], []
for i_ in range(len(data)):
point_1 = (data[0][i_], data[1][i_])
point_2 = (data[2][i_], data[3][i_])
point_x.append(point_1)
point_y.append(point_2)
return point_x[index], point_y[index]
# 画矩形框
def draw_rectangle(frame_, point1, point2):
cv2.rectangle(frame_, point1, point2, rand_color(), random.randint(1, 2))
# 中文读取
def chinese_text():
data_1 = pd.read_table("text.txt", header=None)
text_list = []
for i_ in range(len(data_1)):
text_list.append(data_1[0][i_])
return text_list
# 绘制中文字体
def paint_chinese(frame_, chinese, pos, color):
img_ = Image.fromarray(cv2.cvtColor(frame_, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_)
font = ImageFont.truetype(r'./msyh.ttc', 20, encoding='utf-8')
fill_color = color # (255,0,0)
position = pos # (100,100)
draw.text(position, chinese, font=font, fill=fill_color)
image_ = cv2.cvtColor(np.array(img_), cv2.COLOR_RGB2BGR)
return image_
# 视频保存
def save_video(cap_):
width_ = int(cap_.get(3))
height_ = int(cap_.get(4))
fps_ = cap.get(cv2.CAP_PROP_FPS)
fourcc_ = cv2.VideoWriter_fourcc(*'mp4v')
new_video = cv2.VideoWriter(r'./new_video.mp4', fourcc_, fps_, (width_, height_))
return new_video
if __name__ == '__main__':
start = time.time()
path = r'../../Resources/cat.mp4'
cap = cv2.VideoCapture(path)
new_video_ = save_video(cap)
fps = cap.get(cv2.CAP_PROP_FPS)
total_fps = cap.get(cv2.CAP_PROP_FRAME_COUNT)
current_frame = 0
while True:
ret, frame = cap.read()
if cv2.waitKey(int(np.ceil(total_fps / fps)) // 2) & 0xFF == ord('q'):
break
elif ret is False:
break
for i in range(len(chinese_text())):
start_frame = i * (total_fps / 5)
end_frame = (i + 1) * (total_fps / 5)
# print(current_frame, start_frame, end_frame, rectangle_point(i)[0], rectangle_point(i)[1])
if start_frame <= current_frame <= end_frame:
draw_rectangle(frame, rectangle_point(i)[0], rectangle_point(i)[1])
new_img = paint_chinese(frame, chinese_text()[i], (200, 750), rand_color())
new_video_.write(new_img)
cv2.imshow('cat', new_img)
if current_frame > total_fps:
break
current_frame += 1
cap.release()
new_video_.release()
cv2.destroyAllWindows()
end = time.time()
print(end - start)
实现的部分视频效果如下