OpenCV——图片处理细节

目录

1. 读取图片 

2. 显示图片

3. 保存图片

4.提取彩色图片各个颜色通道

5.彩色图像转灰度图

5.1用opencv将图片转成灰度图

5.2 用opencv将批量图片转灰度图

6.顶帽变换

7.底帽变换

8.同态滤波

9.图片resize

目录

1. 读取图片

2. 显示图片

2.1 cv2.imshow()图像显示不全

3. 保存图片

4.提取彩色图片各个颜色通道

5.彩色图像转灰度图

5.1用opencv将图片转成灰度图

5.2 用opencv将批量图片转灰度图

6.顶帽变换

7.底帽变换

8.同态滤波

9.图片resize

9.1 单张图片resize

9.2 批量图片resize 



1. 读取图片

在OpenCV中使用cv2.imread()函数来加载图片,该函数的形式如下:

cv2.imread(path, flags)

flags:指定以何种方式加载图片,有三个取值:
cv2.IMREAD_COLOR:读取一副彩色图片,图片的透明度会被忽略,默认为该值,实际取值为1;
cv2.IMREAD_GRAYSCALE:以灰度模式读取一张图片,实际取值为0
cv2.IMREAD_UNCHANGED:加载一副彩色图像,透明度不会被忽略。

2. 显示图片

使用cv2.imshow()函数在一个窗口中显示图片,这个窗口自适应图片的大小,其形式如下:

cv2.imshow(winname, mat)

1. winame:一个字符串,表示创建的窗口名字,每一个窗口必须有一个唯一的名字;
2. mat:是一个图片矩阵,numpy.ndarray类型
另外需要注意:

cv2.waitKey()函数

如果没有cv2.waitKey()函数,图像不会显示(也许是一闪而过,我们人眼观察不到),cv2.waitKey()函数是一个键盘绑定函数(相当于让程序在这里挂起暂停执行),他接受一个单位为毫秒的时间,它等待指定时间的键盘事件,在指定时间内发生了键盘事件,程序继续执行,否则必须等到时间结束才能继续执行,参数如果为0表示等待无限长的事件。
cv2.destroyAllWindows()

用来销毁所有已经创建的窗口, 如果需要销毁指定窗口使用cv2.destroyWindow()函数,他接受一个表示窗口名字的名字。

如果我们想放大缩小窗口,必须单独用cv2.namedWindow(),并通过flag参数指定窗口模式为cv2.WINDOW_NORMAL,默认为cv2.WINDOW_AUTOSIZE.

一个放大缩小图片的例子

import numpy as np
import cv2

img = cv2.imshow('picture.jpg')
cv2.namedWindow('image')
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.1 cv2.imshow()图像显示不全

(50条消息) cv2.imshow()图像显示不全_m0_46483236的博客-CSDN博客

在cv2.imshow前加一句: cv2.namedWindow('input',cv2.WINDOW_NORMAL)

import cv2
 
img = cv2.imread('./01.bmp',1) # 0表示灰色图,1表示彩色图,默认为1
cv2.namedWindow('input',cv2.WINDOW_NORMAL)
cv2.imshow('input',img)
cv2.waitKey(0) #保持图像

3. 保存图片

使用cv2.imwrite()函数来保存图片,形式如下:

cv2.imwrite(filename, img)
  • filename: 保存文件的路径名
  • img: 表示图像的numpy.ndarray对象
  • 完整Python程序:
  • import numpy as np
    import cv2
    
    img = cv2.imread('messi5.jpg',0)
    cv2.imshow('image',img)
    k = cv2.waitKey(0)
    ## k = cv2.waitKey(0) & 0xFF  # 64位机器
    if k == 27:         # 按下esc时,退出
        cv2.destroyAllWindows()
    elif k == ord('s'): # 按下s键时保存并退出
        cv2.imwrite('messigray.png',img)
        cv2.destroyAllWindows()

    4.提取彩色图片各个颜色通道

import cv2
import os
# opencv读取的格式是BGR
img = cv2.imread('E:/Nico/Pictures/Saved Pictures/paper illustrate/channel_choice_jpg.jpg')

# 拆分成三通道数据
b, g, r = cv2.split(img)

# 合并三通道数据
img = cv2.merge((b, g, r))
img.shape

# split函数的功能就是如同下面的操作
# 只保留R
# cur_img = img.copy()
# cur_img[:, :, 0] = 0
# cur_img[:, :, 1] = 0
# cv2.imshow('R', cur_img)
# k=cv2.waitKey(0)
# if k==27:
#     cv2.destroyAllWindows()
# elif k==ord('s'):      ## 按下ctrl+s键时保存并退出
#     cv2.imwrite('E:/Nico/Pictures/Saved Pictures/paper illustrate',img)
#     cv2.destroyAllWindows()


# 只保留G
# cur_img = img.copy()
# cur_img[:, :, 0] = 0
# cur_img[:, :, 2] = 0
# cv2.imshow('G', cur_img)
# k=cv2.waitKey(0)
# if k == 27:         # 按下esc时,退出
#     cv2.destroyAllWindows()
# elif k == ord('s'): # 按下ctrl+s键时保存并退出
#     cv2.imwrite('mgreen_chanel.jpg',img)
#     cv2.destroyAllWindows()

# cv2.imwrite('E:/Nico/Pictures/Saved Pictures/paper illustrate/green_chanel.jpg',img)


# # 只保留B
cur_img = img.copy()
cur_img[:, :, 1] = 0
cur_img[:, :, 2] = 0
cv2.imshow('B', cur_img)
k=cv2.waitKey(0)
if k==27:
    cv2.destroyALLWindows()
elif k==ord('s'):
    cv2.imwrite('E:/Nico/Pictures/Saved Pictures/paper illustrate',img)
    cv2.destroyALLWindows()
OpenCV——图片处理细节_第1张图片 绿色通道提取结果

5.彩色图像转灰度图

5.1用opencv将图片转成灰度图

import cv2 as cv
import numpy as np

img = cv.imread("C:/Users/Administrator/Desktop/YJN/Data/FEN JI/861_right.jpg")
h,w = img.shape[:2] #获取图片的high和wide
img_gray=np.zeros([h,w],img.dtype) #创建一张和当前图片大小一样的单通道图片
for i in range(h):
    for j in range(w):
        m = img[i,j]
        img_gray[i,j] =int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将BGR坐标转换为gray坐标
print(img_gray)   #会输出灰度图的高和宽信息
print("image show grap:%s"%img_gray)

cv.imshow("imageshow gray", img_gray)
k=cv.waitKey(0)
if k==27:
    cv.destoryALLWindows()
elif k==ord('s'):
    cv.imwrite('861_right_gray.jpg',img)
    cv.destoryALLWindows()

原参考文中还有更多处理方法

5.2 用opencv将批量图片转灰度图

import cv2
import os

def read_path(file_pathname):
    #遍历该目录下的所有图片文件
    for filename in os.listdir(file_pathname):
        print(filename)
        img = cv2.imread(file_pathname+'/'+filename)
        ####change to gray
      #(下面第一行是将RGB转成单通道灰度图,第二步是将单通道灰度图转成3通道灰度图)
        img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        image_np=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
        #####save figure
        cv2.imwrite(r'F:/YjnJiaNing/val/l4'+"/"+filename,image_np)

#注意*处如果包含家目录(home)不能写成~符号代替
#必须要写成"/home"的格式,否则会报错说找不到对应的目录
#读取的目录
read_path(r"C:/Users/Administrator/Desktop/YJN/Data/FEN JI/fenji_yuantu/val/level_4")
#print(os.getcwd())

6.顶帽变换

原图像减去开运算结果

开运算可以消除暗背景下的较亮区域,所以顶帽变换可以得到原图中灰度较亮的区域。顶帽变换的一个很重要的作用就是校正不均匀光照

import cv2 as cv
import numpy as np

# src = cv.imread('861_right.jpg', cv.IMREAD_GRAYSCALE,flags=0)



img = cv.imread("C:/Users/Administrator/Desktop/YJN/Data/FEN JI/861_right.jpg")
h,w = img.shape[:2]                                     #获取图片的high和wide
img_gray=np.zeros([h,w],img.dtype)                      #创建一张和当前图片大小一样的单通道图片
for i in range(h):
    for j in range(w):
        m = img[i,j]
        img_gray[i,j] =int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将BGR坐标转换为gray坐标
# print(img_gray)
# print("image show grap:%s"%img_gray)
cv.imshow("imageshow gray", img_gray)
k=cv.waitKey(0)
if k==27:
    cv.destoryALLWindows()
elif k==ord('s'):
    cv.imwrite('861_right_gray.png',img)
    cv.destoryALLWindows()

src = cv.imread('861_right_gray.png',flags=0)


# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')

# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:顶帽处理
    result = cv.morphologyEx(src, cv.MORPH_TOPHAT, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        cv.destoryALLWindows()
    elif ch == ord('s'):
        cv.imwrite('imageshow gray', img)
        cv.destoryALLWindows()

        break
cv.destroyAllWindows()
原灰度图

r=5,i=15

r=13,i=20

7.底帽变换

原图片减去闭运算结果

闭运算可以删除亮度较高背景下的较暗区域,所以底帽变换可以得到原图片中灰度较暗的区域,故而又称黑帽变换。 (代码中注释了灰度转化的部分,直接调用了灰度图'861_right_gray.png')

import cv2 as cv
import numpy as np


# img = cv.imread(r"C:/Users/Administrator/Desktop/YJN/Data/FEN JI/861_right.jpg")
# h,w = img.shape[:2]                                     #获取图片的high和wide
# img_gray=np.zeros([h,w],img.dtype)                      #创建一张和当前图片大小一样的单通道图片
# for i in range(h):
#     for j in range(w):
#         m = img[i,j]
#         img_gray[i,j] =int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将BGR坐标转换为gray坐标
# # print(img_gray)
# # print("image show grap:%s"%img_gray)
# cv.imshow("imageshow gray", img_gray)
# k=cv.waitKey(0)
# if k==27:
#     cv.destoryALLWindows()
# elif k==ord('s'):
#     cv.imwrite('861_right_gray.png',img)
#     cv.destoryALLWindows()


src = cv.imread('C:/Users/Administrator/Desktop/YJN/Data/FEN JI/861_right_gray.png',flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:底帽处理
    result = cv.morphologyEx(src, cv.MORPH_BLACKHAT, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        cv.destroyALLWindows()
    elif ch == ord('s'):
        cv.imwirte('bottomhat.png',img)
        cv.destroyAllWindows()
原灰度图

r=5,i=15

r=20,i=15

8.同态滤波

import os
import cv2
from PIL import Image
import numpy as np


def homomorphic_filter(src, d0=10, r1=0.5, rh=2, c=4, h=2.0, l=0.5):
    gray = src.copy()
    if len(src.shape) > 2:
        gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    gray = np.float64(gray)
    rows, cols = gray.shape
    gray_fft = np.fft.fft2(gray)
    gray_fftshift = np.fft.fftshift(gray_fft)
    dst_fftshift = np.zeros_like(gray_fftshift)
    M, N = np.meshgrid(np.arange(-cols // 2, cols // 2), np.arange(-rows//2, rows//2))
    D = np.sqrt(M ** 2 + N ** 2)
    Z = (rh - r1) * (1 - np.exp(-c * (D ** 2 / d0 ** 2))) + r1
    dst_fftshift = Z * gray_fftshift
    dst_fftshift = (h - l) * dst_fftshift + l
    dst_ifftshift = np.fft.ifftshift(dst_fftshift)
    dst_ifft = np.fft.ifft2(dst_ifftshift)
    dst = np.real(dst_ifft)
    dst = np.uint8(np.clip(dst, 0, 255))
    return dst



path = "C:/Users/Administrator/Desktop/YJN/Data/FEN JI/861_right.jpg"
if os.path.isfile(path):
    print("path {} is existence;".format(path))
    img = Image.open(path)
    Img = img.convert('L')
    img = np.array(img)
    print(img, img.shape)
img_new = homomorphic_filter(img)
print("new img shape is {}".format(img_new.shape))
cv2.imwrite("Homo_filter_imshow.png", img_new)
效果图

9.图片resize

9.1 单张图片resize

'''
单张图片resize
'''

import cv2 as cv
img = cv.imread('img.jpg')

cv.imshow('img',img)
#print('原来图片的大小;',img.shape)
resize_img = cv.resize(img,dsize=(400,600))
#print('修改后的图片大小:',resize_img.shape)
cv.imshow('reszie_img',resize_img)
cv.waitKey(0)
cv.destroyAllWindows()

9.2 批量图片resize 

我的图片一共有15张,分别命名为1.jpg-15.jpg

这里的存入文件名为:resize_jm,此文件夹不需要自己手动创建

'''
批量图片resize
'''


import cv2
import numpy as np
import os
 
os.mkdir("E:/Jupyter/OpenCV_face_detect/data/resize_jm")
for i in range(0,15):
    a=i+1
    b=i+1
    img_name = str(a)
    img = cv2.imread("E:/Jupyter/OpenCV_face_detect/data/jm/"+img_name+".jpg")
    img2 = cv2.resize(img, (400,600))
    # # 转换np数组格式
    # pix_img = np.array(img)
    # # 重新reshape图片
    # pix_img = pix_img.reshape(-1, 28, 28, 1)
    # # 查看reshape后的图片shape
    img_name2 = str(b)
    cv2.imwrite("E:/Jupyter/OpenCV_face_detect/data/resize_jm/"+img_name2+".jpg", img2)

参考文:

(6条消息) Opencv基本操作(1)--cv2.imread,cv2.imshow,cv2.imwrite,cv2.cvtColor,cv2.split,cv2.merge,cv2.calcHist_zzccxx5的博客-CSDN博客

(6条消息) opencv 之 颜色通道提取_年少轻与狂的博客-CSDN博客_c++ opencv 提取红色通道opencv 之 颜色通道提取_年少轻与狂的博客-CSDN博客_c++ opencv 提取红色通道(6条消息) opencv 之 颜色通道提取_年少轻与狂的博客-CSDN博客_c++ opencv 提取红色通道

(6条消息) OpenCV——图片的加载、显示、保存(python)_冉茂松的博客-CSDN博客_cv图片保存
(三)图像转灰度图Python实现_水枂的博客-CSDN博客_python将图像转化为灰度图像

(1条消息) Python-OpenCV之形态学处理(腐蚀,膨胀,开运算和闭运算,顶帽变换和底帽变换)_li_il的博客-CSDN博客

你可能感兴趣的:(opencv,计算机视觉,python)