欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

OpenCV-Python-Tutorial安装详情

程序员文章站 2023-02-08 12:18:30
ch01-关于OpenCV opencv坐标系 ch02-安装OpenCV 安装 opencv-python 安装 opencv-contrib-python Windows安装P...

ch01-关于OpenCV opencv坐标系 ch02-安装OpenCV 安装 opencv-python 安装 opencv-contrib-python Windows安装Python版 编译安装 ch03-相关教程及视频 视频 ch04-图片 ch05-视频 VideoCapturepy VideoPlaypy VideoWriterpy two_camerapy ch06-绘图函数 drawpy draw_opencv_logopy Drawing_UTF-8_stringspy 画圆圈py ch07-把鼠标当画笔 draw_circle_rectanglepy MouseCallbackpy 鼠标左右键回调函数py ch08-用滑动条做调色板 createTrackbarpy Trackbar_drawpy ch09-图像的基础操作 img_roipy itemsetpy MakeBorderpy shapepy split_colorpy

ch01-关于OpenCV

opencv坐标系

关于图像坐标系与行列宽高的对应关系大致如下:

row == height == Point.y col == width == Point.x

区分开矩阵 行列;图像x,y

图像x,y: 类似数学中的x,y坐标轴,x对应水平方向,y对应竖直方向,注意图像的原点在左上角,x表示图像的宽度变化(对应矩阵的列变化),y表示图像的高度变化(对应矩阵的行变化)
因此有: col == width == Point.x ;row == height == Point.y

图像坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。

如果要获取图像坐标轴(x,y)对应的像素值
1、image.at(y, x) image为Mat
2、Point(x, y)
3、image[x,y] image为对应图像的矩阵

图像的通道数时n,则使用Mat::at(y, x)时,其y的范围依旧是0到image的height,而x的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。

矩阵行列: 将图像转成对应的矩阵对应的格式[h,w,c],其中h为矩阵的行数对应图像的高度,w为矩阵的列数对应图像的宽度,c为图像的通道数

# -*- coding: utf-8 -*-
# @Time    : 2017/7/28 23:13
# @Author  : play4fun
# @File    : OpenCV图像坐标系_test.py
# @Software: PyCharm

"""
OpenCV图像坐标系_test.py:
"""

# TODO


import numpy as np
import cv2

img = cv2.imread('../data/Lenna.png', cv2.IMREAD_UNCHANGED)
print('img.shape:', img.shape)
logo = cv2.imread('../data/opencv_logo.png', cv2.IMREAD_UNCHANGED)
logo = cv2.resize(logo, (20, 20))
print('logo.shape:', logo.shape)
butterfly= cv2.imread('../data/butterfly.jpg', cv2.IMREAD_UNCHANGED)
butterfly = cv2.resize(butterfly, (20, 20))
print('butterfly.shape:', butterfly.shape)


cv2.imshow('src', img)
cv2.moveWindow('src', 0, 0)

# read color values at position y, x
y = 100
x = 50
(b, g, r) = img[y, x]
# print color values to screen
print('bgr:',b,g,r)

#先行后列
#img[y:y+height,x:width]
img[100:100 + logo.shape[0], 300:300 + logo.shape[1]] = logo[:, :, 0:3]# 两张图片的shape不一样
# img[10:10+logo.shape[0],30:30+logo.shape[1],:]=logo[:,:,0:3]
img[300:300 + logo.shape[1], 100:100 + logo.shape[0]] = butterfly[:, :, 0:3]


font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, text='col=width=X0,row=height-Y0', org=(0, 0), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2,bottomLeftOrigin=True)  # text,
cv2.putText(img, text='col=width=X10,row=height-Y30', org=(10, 30), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2)  # text,
cv2.putText(img, text='col=width=X100,row=height-Y300', org=(100, 300), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2)  # text,
cv2.putText(img, text='col=width-X300,row=height-Y100', org=(300, 100), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2)  # text,

cv2.imshow('img+logo', img)
cv2.imwrite('img_logo.jpg',img)
cv2.moveWindow('img+logo', x=img.shape[0], y=0)
cv2.waitKey(0)

ch02-安装OpenCV

安装 opencv-python

virtualenv -p python3 .cv2 source .cv2/bin/activate pip install opencv-python pip install matplotlib 验证 python -c “import cv2;print(cv2.version,cv2.doc,cv2.file)”

安装 opencv-contrib-python

强烈建议先卸载opencv-python

pip uninstall opencv-python pip install opencv-contrib-python 验证 python -c “import cv2;print(cv2.version,cv2.doc,cv2.file)” 验证 python -c “import cv2;print(print(help(cv2.CascadeClassifier)))”

Windows安装Python版

进入https://www.lfd.uci.edu/~gohlke/pythonlibs下载
opencv_python?3.3.1+contrib?cp36?cp36m?win_amd64.whl (包含contrib模块)

打开cmd 切换到文件路径
pip install opencv_python?3.3.1+contrib?cp36?cp36m?win_amd64.whl

ch04-图片

# -*- coding: utf-8 -*-

import numpy as np
import cv2

print(cv2.__version__)


# img = cv2.imread('messi5.jpg',cv2.IMREAD_COLOR)#读入一副彩色图像。图像的透明度会被忽略   默认参数。
# img = cv2.imread('messi5.jpg', cv2.IMREAD_GRAYSCALE)# Load an color image in grayscale 灰度
img = cv2.imread('messi5.jpg',cv2.IMREAD_UNCHANGED)#包括图像的 alpha 通道

img = cv2.resize(img, (640, 480))

# img.I
# AttributeError: 'numpy.ndarray' object has no attribute 'I'

#
rows,cols,ch=img.shape
print('行/高:',rows,'列/宽:',cols,'通道:',ch)
#图像的宽对应的是列数, 高对应的是行数。

cv2.namedWindow('image', cv2.WINDOW_NORMAL)#可以调整窗口大小
# cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)#自动调整
# cv2.namedWindow('image', cv2.WINDOW_KEEPRATIO)#保持图片比例

# cv2.resizeWindow('image', 200, 200)  # 不起作用?

cv2.imshow('image', img)#窗口会自动调整为图像大小
# 按任意键退出
cv2.waitKey(0)#返回按键的 ASCII 码值

cv2.destroyAllWindows()

#
# cv2.imwrite('messigray.png', img)

ch05-视频

VideoCapture.py

# -*- coding: utf-8 -*-
"""
Created on Fri Jan 3 21:06:22 2014

@author: duan
 """
'''
 注意 当你的程序报错时 你 先检查的是你的摄像头是否能够在其他程 序中正常工作 比如 linux 下的 Cheese 。
'''

import numpy as np
import cv2

cap = cv2.VideoCapture(0)  # 一般的笔 本电脑 有内置摄像头。所以参数就是 0。你可以  设置成 1 或 者其他的来 择别的摄像头

'''
你可以使用函数 cap.get(propId) 来获得  的一些参数信息。   
propId 可以是 0 到 18 之 的任何整数。

其中的一些值可以使用 cap.set(propId,value) 来修改 value 就是 你想  置成的新值。
例如 我可以使用 cap.get(3) cv2.CAP_PROP_FRAME_WIDTH和 cap.get(4) cv2.CAP_PROP_FRAME_HEIGHT来查看每一帧的宽和高。   
默认情况下得到的值是 640X480。但是我可以使用 ret=cap.set(3,320) 和 ret=cap.set(4,240) 来把宽和高改成 320X240。
'''
# ret=cap.set(3,320)
# ret=cap.set(4,240)

# ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)#避免计算量过大
# ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 270)#
#等比缩放
frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)#4 ,720
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)#3   ,1280
frame_height=int(480/frame_width*frame_height)#270
ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)#高
ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)



# while (True):
while cap.isOpened():  # 检查是否成功初始化,否则就 使用函数 cap.open()
    # Capture frame-by-frame
    ret, frame = cap.read()  # ret 返回一个布尔值 True/False
    # print('frame shape:',frame.shape)#(720, 1280, 3)

    frame = cv2.flip(frame, flipCode=1)  # 左右翻转,使用笔记本电脑摄像头才有用。
    # flipCode:翻转方向:1:水平翻转;0:垂直翻转;-1:水平垂直翻转

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame', gray)
    cv2.setWindowTitle('frame', 'COLOR_BGR2GRAY')

    # Property=cv2.getWindowProperty('frame',0)#无用

    # if cv2.waitKey(1) & 0xFF == ord('q'):#不行
    #     break
    key = cv2.waitKey(delay=10)
    if key == ord("q"):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

VideoPlay.py

import numpy as np
import cv2

cap = cv2.VideoCapture('../data/vtest.avi')
# cap = cv2.VideoCapture('output.avi')
# cap = cv2.VideoCapture('Minions_banana.mp4')


# 帧率
fps = cap.get(cv2.CAP_PROP_FPS)  # 25.0
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
# 总共有多少帧
num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('共有', num_frames, '帧')
#
frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # cap.get(3)
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # cap.get(4)
print('高:', frame_height, '宽:', frame_width)

FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES)  # 第0帧
print('当前帧数', FRAME_NOW)  # 当前帧数 0.0

# 读取指定帧,对视频文件才有效,对摄像头无效??
frame_no = 121
cap.set(1, frame_no)  # Where frame_no is the frame you want
ret, frame = cap.read()  # Read the frame
cv2.imshow('frame_no'+str(frame_no), frame)

FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES)
print('当前帧数', FRAME_NOW)  # 当前帧数 122.0

while cap.isOpened():
    ret, frame = cap.read()
    FRAME_NOW = cap.get(cv2.CAP_PROP_POS_FRAMES)  # 当前帧数
    print('当前帧数', FRAME_NOW)

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame', gray)
    key = cv2.waitKey(1)
    if key == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

VideoWriter.py

import numpy as np
import cv2

cap = cv2.VideoCapture(0)
width = 640
ret = cap.set(3, width)
height = 480
ret = cap.set(4, height)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')  # opencv 3.0
# Error: 'module' object has no attribute 'VideoWriter_fourcc'
# fourcc=cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
#jpeg,h263,'m', 'p', '4', 'v'

#
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width, height))

while cap.isOpened():
    ret, frame = cap.read()
    if ret is True:

        frame = cv2.resize(frame, (640, 480))

        # write the flipped frame
        out.write(frame)

        cv2.imshow('frame', frame)

    else:
        break

    key = cv2.waitKey(1)
    if key == ord("q"):
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

two_camera.py

# -*- coding: utf-8 -*-
# @Time    : 2017/8/15 00:19
# @Author  : play4fun
# @File    : two_camera.py
# @Software: PyCharm

"""
two_camera.py:
"""

import cv2
import numpy as np

cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
ret = cap0.set(3, 320)
ret = cap0.set(4, 240)
ret = cap1.set(3, 320)
ret = cap1.set(4, 240)

while cap0.isOpened() and cap1.isOpened():
    ret0, frame0 = cap0.read()
    ret1, frame1 = cap1.read()

    if ret0:
        cv2.imshow('frame0', frame0)
        cv2.setWindowTitle('frame0','On Top')
    if ret1:
        cv2.imshow('frame1', frame1)
        # cv2.moveWindow('frame1', x=frame0.shape[1], y=0)
        cv2.moveWindow('frame1', x=320, y=40)

    key = cv2.waitKey(delay=2)
    if key == ord("q"):
        break

# When everything done, release the capture
cap0.release()
cap1.release()
cv2.destroyAllWindows()

ch06-绘图函数

draw.py

# -*- coding: utf-8 -*-
import numpy as np
import cv2

'''
? img: 你想 绘制图形的 幅图像。
? color: 形状的颜色。以RGB为例  需要传入一个元组 例如 255,0,0 
   代表蓝色。对于灰度图只需要传入灰度值。
? thickness 线条的粗细。如果给一个闭合图形 置为 -1  那么这个图形
就会被填充。 默认值是 1.
? linetype 线条的类型, 8 连接,抗锯齿等。  默认情况是8 连接。cv2.LINE_AA
   为抗锯齿  这样看起来会非常平滑。

'''

# Create a black image
img = np.zeros((512, 512, 3), np.uint8)

# Draw a diagonal blue line with thickness of 5 px
cv2.line(img, pt1=(0, 0), pt2=(511, 511), color=(255, 0, 0), thickness=5)  # pt1, pt2, color, thickness=
# cv2.polylines() 可以 用来画很多条线。只需要把想 画的线放在一 个列表中, 将 列表传给函数就可以了。每条线 会被独立绘制。 这会比用 cv2.line() 一条一条的绘制 要快一些。
# cv2.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
cv2.arrowedLine(img,pt1=(21, 13), pt2=(151, 401), color=(255, 0, 0), thickness=5)

cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)

cv2.circle(img, center=(447, 63), radius=63, color=(0, 0, 255), thickness=-1)  # center, radius, color, thickness=None

# 一个参数是中心点的位置坐标。 下一个参数是长轴和短轴的长度。椭圆沿逆时针方向旋转的角度。
# 椭圆弧演顺时针方向起始的角度和结束角度 如果是 0 很 360 就是整个椭圆
cv2.ellipse(img, center=(256, 256), axes=(100, 50), angle=0, startAngle=0, endAngle=180, color=255,
            thickness=-1)  # center, axes, angle, startAngle, endAngle, color, thickness=

pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32)
pts = pts.reshape((-1, 1, 2))
# 这里 reshape 的第一个参数为-1, 表明这一维的长度是根据后面的维度的计算出来的。
# 注意 如果第三个参数是 False 我们得到的多边形是不闭合的 ,首 尾不相  连 。

font = cv2.FONT_HERSHEY_SIMPLEX
#org :Bottom-left corner of the text string in the image.左下角
#或使用 bottomLeftOrigin=True,文字会上下颠倒
cv2.putText(img, text='bottomLeftOrigin', org=(10, 400), fontFace=font, fontScale=1, color=(255, 255, 255), thickness=1,bottomLeftOrigin=True)#text, org, fontFace, fontScale, color, thickness=
cv2.putText(img, text='OpenCV', org=(10, 500), fontFace=font, fontScale=4, color=(255, 255, 255), thickness=2)#text, org, fontFace, fontScale, color, thickness=

# 所有的绘图函数的返回值都是 None ,所以不能使用 img = cv2.line(img,(0,0),(5

winname = 'example'
cv2.namedWindow(winname, 0)
cv2.imshow(winname, img)

cv2.imwrite("example.png", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

draw_opencv_logo.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/11 下午7:07
# @Author  : play4fun
# @File    : draw_opencv_logo.py
# @Software: PyCharm

"""
draw_opencv_logo.py:Try to create the logo of OpenCV using drawing functions available in OpenCV.
"""

import numpy as np
import cv2  # 3.0.0-dev
import math

r1 = 70
r2 = 30

ang = 60

d = 170
h = int(d / 2 * math.sqrt(3))

dot_red = (256, 128)
dot_green = (int(dot_red[0] - d / 2), dot_red[1] + h)
dot_blue = (int(dot_red[0] + d / 2), dot_red[1] + h)

# tan = float(dot_red[0]-dot_green[0])/(dot_green[1]-dot_red[0])
# ang = math.atan(tan)/math.pi*180

red = (0, 0, 255)
green = (0, 255, 0)
blue = (255, 0, 0)
black = (0, 0, 0)

full = -1

img = np.zeros((512, 512, 3), np.uint8)
# img = np.ones((512, 512, 3), np.uint8)

cv2.circle(img, dot_red, r1, red, full)
cv2.circle(img, dot_green, r1, green, full)
cv2.circle(img, dot_blue, r1, blue, full)
cv2.circle(img, dot_red, r2, black, full)
cv2.circle(img, dot_green, r2, black, full)
cv2.circle(img, dot_blue, r2, black, full)

cv2.ellipse(img, dot_red, (r1, r1), ang, 0, ang, black, full)
cv2.ellipse(img, dot_green, (r1, r1), 360 - ang, 0, ang, black, full)
cv2.ellipse(img, dot_blue, (r1, r1), 360 - 2 * ang, ang, 0, black, full)

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, text='OpenCV', org=(15, 450), fontFace=font, fontScale=4, color=(255, 255, 255), thickness=10)#text,

cv2.imwrite("opencv_logo.png", img)
# cv2.imwrite("opencv_logo2.png", img)

Drawing_UTF-8_strings.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/23 下午9:11
# @Author  : play4fun
# @File    : Drawing_UTF-8_strings.py
# @Software: PyCharm

"""
Drawing_UTF-8_strings.py:

https://fireant.github.io/misc/2017/01/28/ttf-opencv.html
"""

import cv2
import numpy as np

img = np.zeros((100, 300, 3), dtype=np.uint8)

ft = cv2.freetype.createFreeType2()  # 需要安装freetype模块 cv2' has no attribute 'freetype'
# ft.loadFontData(fontFileName='Ubuntu-R.ttf',id=0)
# ft.loadFontData(fontFileName='/usr/share/fonts/truetype/freefont/FreeSans.ttf',id=0)#不支持中文
# ft.loadFontData(fontFileName='/usr/share/fonts-droid/truetype/DroidSansFallback.ttf',id=0)#树莓派,搞定

#sudo apt-get install ttf-wqy-zenhei  #安装字体
ft.loadFontData(fontFileName='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc', id=0)  # 文泉驿的开源中文字体


ft.putText(img=img,
           # text='Quick Fox',
           text='你好中文',
           org=(15, 70),
           fontHeight=60,
           color=(255, 255, 255),
           thickness=-1,
           line_type=cv2.LINE_AA,
           bottomLeftOrigin=True)

# cv2.imwrite('freetype.png', img)
cv2.imshow('freetype', img)
cv2.waitKey(0)

画圆圈.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/17 下午12:03
# @Author  : play4fun
# @File    : 画圆圈.py
# @Software: PyCharm

"""
画圆圈.py:随机覆盖,不同颜色,
"""
from time import sleep
import cv2
import numpy as np


def click_event(event, x, y, flags, param):
    '''
    用左键点击屏幕,打印坐标
    :param event:
    :param x:
    :param y:
    :param flags:
    :param param:
    :return:
    '''
    if event == cv2.EVENT_LBUTTONDOWN:
        print(x, y, flags, param)


cv2.namedWindow('Canvas', cv2.WINDOW_GUI_EXPANDED)
cv2.setMouseCallback("Canvas", click_event)

canvas = np.zeros((300, 300, 3), dtype="uint8")
while True:
    try:
        for i in range(0, 25):
            radius = np.random.randint(5, high=200)
            color = np.random.randint(0, high=256, size=(3,)).tolist()
            pt = np.random.randint(0, high=300, size=(2,))
            cv2.circle(canvas, tuple(pt), radius, color, -1)

        cv2.imshow("Canvas", canvas)

        key = cv2.waitKey(1000)  # 等待1秒
        if key == ord('q'):
            break
        else:
            # sleep(1)
            continue
    except KeyboardInterrupt as e:
        print('KeyboardInterrupt', e)
    finally:
        cv2.imwrite('random-circles2.jpg', canvas)

ch07-把鼠标当画笔

draw_circle_rectangle.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np

# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
ix, iy = -1, -1


# 创建回调函数    #回调函数包含两部分 一部分画矩形 一部分画圆圈
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode
    # 当按下左键是返回起始位置坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        if drawing is True:
            if mode is True:
                cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
            else:
                # 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
                cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
                # 下面注释掉的代码是起始点为圆心,起点到终点为半径的
                # r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))
                # cv2.circle(img, (x, y), r, (0, 0, 255), -1)

    elif event == cv2.EVENT_LBUTTONUP:  # 当鼠标松开停止绘画。
        drawing = False
        # if mode == True:
        #     cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
        # else:
        #     cv2.circle(img, (x, y), 5, (0, 0, 255), -1)


#
img = np.zeros((512, 512, 3), np.uint8)
mode = False

cv2.namedWindow('image', 0)
cv2.setMouseCallback('image', draw_circle)
while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1)  # & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == ord("q"):
        break

MouseCallback.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np


# mouse callback function


def draw_circle(event, x, y, flags, param):  # 只用做一件事:在双击过的地方绘 制一个圆圈。
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 100, (255, 0, 0), -1)


# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)

cv2.setMouseCallback('image', draw_circle)

while True:
    cv2.imshow('image', img)
    # if cv2.waitKey(20) & 0xFF == 27:
    #     break
    key = cv2.waitKey(1)
    if key == ord("q"):
        break
cv2.destroyAllWindows()

鼠标左右键回调函数.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/17 下午6:19
# @Author  : play4fun
# @File    : 鼠标左右键回调函数.py
# @Software: PyCharm

"""
鼠标左右键回调函数.py:
"""

import cv2


def click_event(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print(x, y)

    if event == cv2.EVENT_RBUTTONDOWN:
        red = img[y, x, 2]
        blue = img[y, x, 0]
        green = img[y, x, 1]
        print(red, green, blue)

        strRGB = str(red) + "," + str(green) + "," + str(blue)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, strRGB, (x, y), font, 1, (255, 255, 255), 2)
        cv2.imshow('original', img)


img = cv2.imread('../data/messi5.jpg')
cv2.imshow('original', img)

cv2.setMouseCallback("original", click_event)
cv2.waitKey(0)
cv2.imwrite('putText.jpg',img)

cv2.destroyAllWindows()

ch08-用滑动条做调色板

createTrackbar.py

# -*- coding: utf-8 -*-

import cv2
import numpy as np


def nothing(x):
    pass


# Create a black image, a window
img = np.zeros((300, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)

# create trackbars for color change
cv2.createTrackbar('R', 'image', 0, 255, nothing)
cv2.createTrackbar('G', 'image', 0, 255, nothing)
cv2.createTrackbar('B', 'image', 0, 255, nothing)

# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv2.createTrackbar(switch, 'image', 0, 1, nothing)
# 只有当 转换按钮 指向 ON 时 滑动条的滑动才有用,否则窗户 都是黑的。

while True:

    # get current positions of four trackbars
    r = cv2.getTrackbarPos('R', 'image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    s = cv2.getTrackbarPos(switch, 'image')  # 另外一个重要应用就是用作转换按钮

    if s == 0:
        img[:] = 0
    else:
        img[:] = [b, g, r]

    cv2.imshow('image', img)
    k = cv2.waitKey(1)  # & 0xFF
    if k == ord("q"):
        break

cv2.destroyAllWindows()

Trackbar_draw.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np


def nothing(x):
    pass


# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
ix, iy = -1, -1

'''
cv2.getTrackbarPos() 函数的第一个参数是滑动条的名字 
第二个参数 是滑动条被放置窗口的名字 
第三个参数是滑动条的默认位置。
第四个参数是滑动条的最大值 
第五个函数是回调函数, 每次滑动条的滑动都会调用回调函 数。
回调函数通常都会含有一个默认参数 就是滑动条的位置
'''


# 创建回调函数
def draw_circle(event, x, y, flags, param):
    r = cv2.getTrackbarPos('R', 'image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    color = (b, g, r)

    global ix, iy, drawing, mode
    # 当按下左键是返回起始位置坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        if drawing is True:
            if mode is True:
                cv2.rectangle(img, (ix, iy), (x, y), color, -1)
            else:
                # 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
                cv2.circle(img, (x, y), 3, color, -1)
                # 下面注释掉的代码是起始点为圆心,起点到终点为半径的
                # r=int(np.sqrt((x-ix)**2+(y-iy)**2))
                # cv2.circle(img,(x,y),r,(0,0,255),-1)

                # 当鼠标松开停止绘画。
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        # if mode==True:
        #     cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        # else:
        #     cv2.circle(img,(x,y),5,(0,0,255),-1)


img = np.zeros((512, 512, 3), np.uint8)
mode = False

cv2.namedWindow('image')
cv2.createTrackbar('R', 'image', 0, 255, nothing)
cv2.createTrackbar('G', 'image', 0, 255, nothing)
cv2.createTrackbar('B', 'image', 0, 255, nothing)
cv2.setMouseCallback('image', draw_circle)

while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1)  # & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == ord("q"):
        break

ch09-图像的基础操作

9.img_roi.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np

'''
例如我们 检测一副图像中 眼睛的位置 我们 先应该在图像中找到脸 再在脸的区域中找眼睛 
而不是 直接在一幅图像中搜索。这样会提高程序的准确性和性能。
'''

img=cv2.imread('../data/messi5.jpg')

ball=img[280:340,330:390]
img[273:333,100:160]=ball #修改像素值



cv2.namedWindow("messi",0)
cv2.imshow("messi",img)
cv2.waitKey(0)

9.itemset.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np

img = cv2.imread('../data/messi5.jpg')

#
px = img[100, 100]
print(px)
blue = img[100, 100, 0]
print(blue)

#
img[100, 100] = [255, 255, 255]
print(img[100, 100])

# 获取像素值及修改的更好方法。
print(img.item(10, 10, 2))
img.itemset((10, 10, 2), 100)
print(img.item(10, 10, 2))

9.MakeBorder.py

# -*- coding: utf-8 -*-

import cv2
import numpy as np
from matplotlib import pyplot as plt

# 为图像扩边,填充
#如果你想在图像周围创建一个边框,就像相框一样
# 经常在卷积运算或 0 填充时被用到。

BLUE = [255, 0, 0]

img1 = cv2.imread('../data/opencv_logo.png')

replicate = cv2.copyMakeBorder(img1, top=10, bottom=10, left=10, right=10, borderType=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)  # value 边界颜色

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()

9.shape.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np

img = cv2.imread('../data/messi5.jpg', 0)  # gray
print(img.shape)

img = cv2.imread('../data/messi5.jpg')
# print(img.shape)
rows, cols, ch = img.shape
print('行/高:', rows, '列/宽:', cols, '通道:', ch)

print(img.size)
print(img.dtype)#uint8
#注意 在   debug 时 img.dtype非常重要。因为在 OpenCV- Python 代码中经常出现数据类型的不一致。

9.split_color.py

# -*- coding: utf-8 -*-
import cv2
import numpy as np
#拆分及合并图像通道

img=cv2.imread('../data/messi5.jpg')

#
b,g,r=cv2.split(img)#比较耗时的操作,请使用numpy 索引
img=cv2.merge(b,g,r)

#
b=img[:,:,0]

#使所有像素的红色通道值都为 0,你不必先拆分再赋值。
# 你可以 直接使用 Numpy 索引,这会更快。
img[:,:,2]=0