csdn 有个OpenCV技能树,做练习题的笔记放在那边的帖子找不到了,先在这里做个记录,opencv基础篇。
安装:
安装命令:
如果没配置国内镜像,可以加个镜像源,速度快点。
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
检验安装:
进入python环境中,输入程序,若正常输出版本,则安装成功。
import cv2
print(cv2.__version__)
基本操作
读取与展示图像:
import cv2
if __name__ == '__main__':
img = cv2.imread("lena.png",1) #BGR读取 => img(ndarray)
cv2.imshow("lena", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
保存图像:
import cv2
cv2.imwrite('new.png',img)
获取像素颜色:
BGR格式:
import numpy as np
import cv2
if __name__ == '__main__':
img = cv2.imread('lena.png', cv2.IMREAD_COLOR)
px = img[100, 100]
print(f'blue:{px[0]}, green:{px[1]}, red:{px[2]}')
LAB格式:
import numpy as np
import cv2 as cv
if __name__ == '__main__':
img = cv.imread('lena.png', cv.COLOR_BGR2LAB)
px = img[100, 100]
print(f'L:{px[0]}, a:{px[0]}, b:{px[0]}')
HSV格式
import numpy as np
import cv2 as cv
if __name__ == '__main__':
img = cv.imread('lena.png', cv.COLOR_BGR2HSV)
px = img[100, 100]
print(f'Hue:{px[0]}, Saturation:{px[0]}, Value:{px[0]}')
Mat 属性
height, width, channels = img.shape
图片绿化(颜色通道操作)
题目来源 1
代码:
import numpy as np
import cv2
import math
def hacker(img):
height, width, channels = img.shape
for i in range(0, width):
for j in range(0, height):
b,g,r = img.item((i, j, 0)),img.item((i, j, 1)), img.item((i, j, 2))
hack_b = int(math.pow(b/256.0, 3/2) * 256)
hack_g = int(math.pow(g/256.0, 4/5) * 256)
hack_r = int(math.pow(r/256.0, 3/2) * 256)
img.itemset((i, j, 0), hack_b)
img.itemset((i, j, 1), hack_g)
img.itemset((i, j, 2), hack_r)
if __name__ == '__main__':
img_origin = cv2.imread('lena.png', cv2.IMREAD_COLOR)
img = cv2.imread('lena.png', cv2.IMREAD_COLOR)
print(img.size)
print(img.shape)
hacker(img)
print('显示图片,请按任意键退出')
numpy_horizontal_concat = np.concatenate((img_origin, img), axis=1)
cv2.imshow('Lena图片黑客帝国化', numpy_horizontal_concat)
cv2.waitKey()
cv2.destroyAllWindows()
复制足球
题源来源2:
先将ball提取出来,=> img
设定x y 方向上的偏移,=> x y (px)
最后,依次填补 => img[ , ] = ball
import cv2
import numpy as np
if __name__ == '__main__':
img = cv2.imread('ball.jpg', cv2.IMREAD_COLOR)
start = [493, 594]
end = [112, 213]
ball = img[start[0]:start[1], end[0]:end[1]]
x_step = 101
y_step = 10
for i in range(-1, 4):
x_offset = x_step*i
y_offset = y_step*i
img[start[0]-y_offset:start[1]-y_offset, end[0]+x_offset:end[1]+x_offset] = ball
cv2.imshow("ball_continue", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
甲壳虫乐队
题目来源3
import numpy as np
import cv2
if __name__ == '__main__':
bug_img = cv2.imread("bug.jpg")
bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
bug_img_concat = np.concatenate(
(bug_img, bug_img_gray_by_BGR_space),
axis=1
)
cv2.imwrite("bug_band.jpg", bug_img_concat)
cv2.imshow('甲壳虫乐队', bug_img_concat)
cv2.waitKey(0)
cv2.destroyAllWindows()
早起的鸟儿有虫吃
题源4
import numpy as np
import cv2
if __name__ == '__main__':
cap = cv2.VideoCapture('birds.mp4')
out = ...
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
out = cv2.VideoWriter(
'birds_concat.mp4',
cv2.VideoWriter_fourcc(*'mp4v'),
fps,
(width*2, height)
)
i = 0
while(cap.isOpened()):
ret, bird_frame = cap.read()
if bird_frame is None:
break
bird_flip_frame = cv2.flip(bird_frame, 0)
bird_concat_frame = np.concatenate(
(bird_frame, bird_flip_frame),
axis=1
)
cv2.imshow('bird_concat_frame', bird_concat_frame)
if i % 10 == 0:
out.write(bird_concat_frame)
i += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
out.release()
cap.release()
cv2.destroyAllWindows()
甲壳虫的base64之旅
把图片编码成 Base64,再从Base64解码出来。5
import numpy as np
import cv2
import base64
def img_to_base64(img):
return base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()
def img_from_base64(img_base64):
jpg_original = base64.b64decode(img_base64)
jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
img = cv2.imdecode(jpg_as_np, flags=1)
return img
if __name__ == '__main__':
img = cv2.imread('bug.jpg')
img_base64 = img_to_base64(img)
img = img_from_base64(img_base64)
cv2.imshow('img_decode', img)
cv2.waitKey()
cv2.destroyAllWindows()
矩形涂鸦画板
题目来源6
编写一个矩形涂鸦画板,实现功能:
鼠标左键按下拖动绘制矩形,鼠标左键弹起时完成绘制
按’c’键清空画板
按’ESC’键退出
import numpy as np
import cv2 as cv
from random import randint
class Painter:
def __init__(self) -> None:
self.mouse_is_pressed = False
self.last_pos = (-1, -1)
self.width = 300
self.height = 512
self.img = np.zeros((self.width, self.height, 3), np.uint8)
self.window_name = 'painter'
self.color = None
def run(self):
print('画板,拖动鼠标绘制矩形框,按ESC退出,按c键清空画板')
cv.namedWindow(self.window_name)
cv.setMouseCallback(
self.window_name,
lambda event, x, y, flags, param: self.on_draw(
event, x, y, flags, param
)
)
while True:
cv.imshow(self.window_name, self.img)
k = cv.waitKey(1) & 0xFF
if k == ord('c'):
self.clean()
elif k == 27:
break
cv.destroyAllWindows()
def on_draw(self, event, x, y, flags, param):
pos = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
self.mouse_is_pressed = True
self.last_pos = pos
elif event == cv.EVENT_MOUSEMOVE:
if self.mouse_is_pressed == True:
self.begin_draw_rectangle(self.last_pos, pos)
elif event == cv.EVENT_LBUTTONUP:
self.end_draw_rectangle(self.last_pos, pos)
self.mouse_is_pressed = False
def clean(self):
cv.rectangle(self.img, (0, 0), (self.height, self.width), (0, 0, 0), -1)
def begin_draw_rectangle(self, pos1, pos2):
if self.color is None:
self.color = (randint(0, 256), randint(0, 256), randint(0, 256))
cv.rectangle(self.img, pos1, pos2, self.color, -1)
def end_draw_rectangle(self, pos1, pos2):
self.color = None
if __name__ == '__main__':
p = Painter()
p.run()