Skip to content

Latest commit

 

History

History
229 lines (157 loc) · 8.73 KB

02.图像的基础操作、色彩空间.md

File metadata and controls

229 lines (157 loc) · 8.73 KB

图像的基础操作、色彩空间

1、图像的基础操作

获取并修改像素值

​ 首先我们需要读入一幅图像:

import cv2
import numpy as np
img=cv2.imread('C:\install\pycharm\code\pythonProject4\1.jpg')  #这里路径,windows下都是用斜杆隔开,linux下都是用反斜杠/

​ 你可以根据像素的行和列的坐标获取他的像素值。对 BGR 图像而言,返回 值为 B,G,R 的值。对灰度图像而言,会返回他的灰度值。

import cv2 as cv
import numpy as np
img=cv.imread('C:\install\pycharm\code\pythonProject4/1.png')  #windows下都是用斜杆隔开,linux下都是用反斜杠/
px=img[100,100]
print(px)
blue=img[100,100,0]
print(blue)
## [70 61 74]   这里具体的数值和你使用的图片有关
## 70

​ 你可以以类似的方式修改像素值。

import cv2 as cv
import numpy as np
img=cv.imread('C:\install\pycharm\code\pythonProject4/1.png')  #windows下都是用斜杆隔开,linux下都是用反斜杠/
px=img[100,100]
img[100,100]=[255,255,255]
print(px)
## [255 255 255]

​ 更好的像素访问和编辑方法:

import cv2 as cv
import numpy as np
img=cv.imread('C:\install\pycharm\code\pythonProject4/1.png')  #windows下都是用斜杆隔开,linux下都是用反斜杠/
print(img.item(10,10,2))
img.itemset((10,10,2),100)
print(img.item(10,10,2))
#19
#100

获取图像属性

​ 图像的属性包括:行,列,通道,图像数据类型,像素数目等 img.shape 可以获取图像的形状。他的返回值是一个包含行数,列数, 通道数的元组。

print(img.shape) #(300, 555, 3)

​ Note:如果图像是灰度的,返回的元组只包含行数和列数,所以这是检查加载的图像是灰度的还是彩色的一个好方法。

​ img.size 可以返回图像的像素数目:

print(img.size)  #499500

​ img.dtype 返回的是图像的数据类型

print( img.dtype )  #uint8

图像 ROI

​ ROI: region of interest

​ 有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中 眼睛的位置,我们首先应该在图像中找到脸,当获得一张人脸时,我们选择单独的人脸区域,并在其中搜索眼睛,而不是搜索整个图像。它提高了准确性(因为眼睛总是在脸上:D)和表现(因为我们在小范围内搜索)。

这样会提高程序的准确性和性能。 ROI 也是使用 Numpy 索引来获得的。这里我们任选一个区域

something = img[0:300, 70:350]
cv.imshow('something',something)

​ 输出:

02-1

拆分及合并图像通道

​ 有时我们需要对 BGR 三个通道分别进行操作。这是你就需要把 BGR 拆 分成单个通道。有时你需要把独立通道的图片合并成一个 BGR 图像。你可以 这样做:

b,g,r = cv.split(img)
img = cv.merge((b,g,r))

​ 或者

b = img[:,:,0]

​ 假如你想使所有像素的红色通道值都为 0,你不必先拆分再赋值。你可以 直接使用 Numpy 索引,这会更快。

img[:,:,2] = 0

​ Note:cv.split() 是一个比较耗时的操作。只有真正需要时才用它,能用 Numpy 索引就尽量用。

2、颜色空间

Opencv中常用的颜色空间就三种BGR、HSV、灰度。

颜色空间转换

​ 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种:BGR↔Gray 和 BGR↔HSV。

​ 我们要用到的函数是:cv.cvtColor(input_image,flag),其中 flag 就是转换类型。

​ 对于 BGR↔Gray 的转换,我们要使用的 flag 就是cv.COLOR_BGR2GRAY。 同样对于 BGR↔HSV 的转换,我们用的 flag 就是 cv.COLOR_BGR2HSV。 你还可以通过下面的命令得到所有可用的 flag。

​ 代码如下:

import cv2 as cv
flags = [i for i in dir(cv) if i.startswith('COLOR_')]
print( flags )

​ Note:在 OpenCV 的 HSV 格式中,H(色彩/色度)的取值范围是 [0,179], S(饱和度)的取值范围 [0,255],V(亮度)的取值范围 [0,255]。但是不 同的软件使用的值可能不同。所以当你需要拿 OpenCV 的 HSV 值与其他软 件的 HSV 值进行对比时,一定要记得归一化。

物体跟踪

​ 现在我们知道怎样将一幅图像从 BGR 转换到 HSV 了,我们可以利用这 一点来提取带有某个特定颜色的物体。在 HSV 颜色空间中要比在 BGR 空间 中更容易表示一个特定颜色。在我们的程序中,我们要提取的是一个蓝色的物 体。下面就是就是我们要做的几步:

  • 从视频中获取每一帧图像
  • 将图像转换到 HSV 空间
  • 设置 HSV 阈值到蓝色范围。
  • 获取蓝色物体,当然我们还可以做其他任何我们想做的事,比如:在蓝色 物体周围画一个圈。

代码如下:

import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
    # Take each frame
    _, frame = cap.read()
    # Convert BGR to HSV
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    # Threshold the HSV image to get only blue colors
    mask = cv.inRange(hsv, lower_blue, upper_blue)
    # Bitwise-AND mask and original image
    res = cv.bitwise_and(frame,frame, mask= mask)
    cv.imshow('frame',frame)
    cv.imshow('mask',mask)
    cv.imshow('res',res)
    k = cv.waitKey(5) & 0xFF
    if k == 27:
        break
cv.destroyAllWindows()

效果如下:

20210206002911

我这个调参调的不是特别好,你们可以自己调一下。

​ Note:注意:图像中仍然有一些噪音,我们会在后面的章节中介绍如何消减噪音。 这是物体跟踪中最简单的方法。当你学习了轮廓之后,你就会学到更多 相关知识,那是你就可以找到物体的重心,并根据重心来跟踪物体,仅仅在摄像头前挥挥手就可以画出同的图形,或者其他更有趣的事。

跟踪对象的 HSV 值

​ 你可以使用函数 cv.cvtColor() 实现。但是现在你要传入的参数是(你想要 的)BGR 值而不是一副图。

​ 代码如下:

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV)
print( hsv_green )
[[[ 60 255 255]]]

​ 现在你可以分别用 [H-100,100,100] 和 [H+100,255,255] 做上下阈值。

3、程序性能检测

​ 通过计算程序执行时间判断程序性能:

cv.getTickCount 函数返回从参考点到这个函数被执行的时钟数。所 以当你在一个函数执行前后都调用它的话,你就会得到这个函数的执行时间 (时钟数)。**cv.getTickFrequency**返回时钟频率,或者说每秒钟的时钟数。所以 你可以按照下面的方式得到一个函数运行了多少秒:

e1 = cv.getTickCount()
# your code execution
e2 = cv.getTickCount()
time = (e2 - e1)/ cv.getTickFrequency()

参考文献


思考题

  1. HSV和BGR三原色在图片信息存储的差别在哪?

练习题

  1. 编写一段程序实现以下功能:

    代码调用电脑摄像头,寻找视野中任意颜色(自定)并具有一定大小的物体,并用矩形框处,最后显示在图像上;