python-opencv4学习——图像初探

opencv学习

  • 显示图像
  • 图像基本操作
    • 访问和修改像素值
    • 访问ROI区域

本文主要记录学习opencv4的过程,以前只是接触过一点点图像方面的东西,工作后没有弄相关的东西都快忘光了,复习一下顺便学习新的opencv4(笑)

显示图像

学习opencv的第一步当然是显示图像,先拿我母校的图片试试水==。显示图像主要靠cv.imread()加载图像,通过cv.imshow()来显示图像代码如下

import cv2
import cv2 as cv

src = cv.imread("road.jpg")
cv.imshow('road', src)
cv.waitKey(0)
cv.destroyAllWindows()

cv.waitKey(0)是为了让图像无限期等待下一次敲击键而不会立刻关掉,由于我的图片太大,我加入cv.namedWindow使得图片的大小可以通过外框的拉伸实现,如下

src = cv.imread("road.jpg")
cv.namedWindow('road',cv.WINDOW_NORMAL)
cv.imshow('road', src)
cv.waitKey(0)
cv.destroyAllWindows()

其实cv.namedWindow是先生成了一个窗口,然后把图片扔进去,主要在于后面的参数。默认其实是cv.WINDOW_AUTOSIZE,我们这里改为cv.WINDOW_NORMAL使得窗口的大小可以调节,然后显示图片。
另外一种方式用resize重新设置图片的大小,再把图片导出来,如下

src = cv.imread("road.jpg")
pic_resize = cv2.resize(src, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_AREA)
cv.imshow('road', src)
cv.waitKey(0)
cv.destroyAllWindows()

最后图片呈现python-opencv4学习——图像初探_第1张图片
改用灰度的话可以修改imread函数如下

src = cv.imread("road.jpg",0)

可以读入灰度图像python-opencv4学习——图像初探_第2张图片
加上imwrite保存图像并退出,可以使用waitkey去判断按键再考虑要不要保存,如下

src = cv.imread("road.jpg",0)
pic_resize = cv2.resize(src, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_AREA)
cv.imshow('road', pic_resize)
k = cv.waitKey(0)
if k == 27: # 等待ESC退出
    cv.destroyAllWindows()
elif k == ord('s'):  # 等待关键字s,保存和退出
    cv.imwrite('road_gray.png', pic_resize)

也可以用Matplotlib库来显示图片,但是不能显示彩色的,好像是opencv加载的方式和Matplotlib不一致

plt.imshow(src, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([]) # 隐藏 x 轴和 y 轴上的刻度值
plt.show()

图像基本操作

访问和修改像素值

一般来说彩色的图像的点会由R,G,B三种值构成,而灰度图像就只会显示灰度值,可以通过坐标访问对应位置的像素值。
以刚才的图像为例,进行坐标点[100,100]的像素值读取可以如下写

px = src[100, 100]
print("pixel of the point [100,100] is", px)

当图像为彩色时,得到的结果如下,额这里数组的排序是BGR,要注意不能搞混了。

pixel of the point [100,100] is [11 27 26]

为灰色时即前面说到的imread显示灰度图像然后再读像素值

pixel of the point [100,100] is 29

可以用src.shape返回图像的行列,src.size返回像素总数,src.dtype返回数据类型

print("图像形状:", src.shape, '\n像素总数:', src.size, '\n数据类型:', src.dtype)

src.shape结果是行,列,通道数元组,结果如下

图像形状: (4032, 2688, 3) 
像素总数: 32514048 
数据类型: uint8

接下来是修改像素的方式,
最简单的修改像素的方式就是直接对图像某个点进行像素修改,直接用数组赋值的方式就可以了。。。即

src[100, 100] = [255, 255, 255]
print(src[100, 100])

当然可以只访问单个颜色的像素值,

blue = src[200, 200, 0]

当然,访问单个像素值一般用array.item(),修改用array.itemset()会比较好。

访问ROI区域

偶尔图像处理会关注一些特殊区域,我们称为roi区域,为了减少图像处理的负担,我们可以选取感兴趣的部分进行处理,一般来说ROI区域的选取可以直接用坐标来获取如

ROIArea = img[280:340, 330:390]

我这里简单地使用了按键回调的机制写了个画框图来选取ROI区域的机制如下,按esc退出图像

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

src = cv.imread("road.jpg")
pic_resize = cv2.resize(src, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_AREA)

selecting = False  # 如果按下鼠标,则为真
ix_start = 0
iy_start = 0
ROI_corner = np.empty(4)
# 先初始化roi为整个图像
ROI_Area = pic_resize[0:pic_resize.shape[0], 0:pic_resize.shape[1]]

def ROIselect(event,x,y,flags,param):
    global ix_start, iy_start, selecting, ROI_corner
    if event == cv.EVENT_LBUTTONDOWN:
        selecting = True
        ix_start, iy_start = x, y
    elif event == cv.EVENT_LBUTTONUP:
        if selecting == True :
            # 让矩形可以反向伸缩
            ROI_corner[0] = min(ix_start, x)
            ROI_corner[1] = min(iy_start, y)
            ROI_corner[2] = max(ix_start, x)
            ROI_corner[3] = max(iy_start, y)
        print("框的坐标为:\n")
        print("矩形框左上角坐标:")
        print(ROI_corner[0], ROI_corner[1])
        print("矩形框右下角坐标:")
        print(ROI_corner[2], ROI_corner[3])
        cv.rectangle(pic_resize, (int(ROI_corner[0]), int(ROI_corner[1])), (int(ROI_corner[2]), int(ROI_corner[3])), (0, 255, 0), 2)
        ROI_Area = pic_resize[ROI_corner[0]:ROI_corner[1], ROI_corner[2]:ROI_corner[3]]
        selecting = False
cv.namedWindow('image')
cv.setMouseCallback('image', ROIselect)
while(1):
    cv.imshow('image', pic_resize)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

这里发现cv.rectangle的坐标参数只接收int的数值,所以转换了一下, ROI_Area 先是被初始化为整幅图像,然后变为框里的部分,效果如图
python-opencv4学习——图像初探_第3张图片

矩形框左上角坐标:
220.0 375.0
矩形框右下角坐标:
391.0 523.0

顺便加个显示roi坐标的字

text_display1 = 'roi zone:' + str(ROI_corner[0]) + ':' + str(ROI_corner[2]) + ','
        text_display2 = str(ROI_corner[1]) + ':' + str(ROI_corner[3])
        cv.putText(pic_resize, text_display1, (int(ROI_corner[2]) + 10, int(ROI_corner[3]) + 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv.LINE_AA)
        cv.putText(pic_resize, text_display2, (int(ROI_corner[2]) + 10, int(ROI_corner[3]) + 30), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv.LINE_AA)

python-opencv4学习——图像初探_第4张图片
ok,Done

你可能感兴趣的:(opencv,opencv,图像识别)