OpenCV——图片处理细节

发布于:2022-12-22 ⋅ 阅读:(439) ⋅ 点赞:(0)

目录

1. 读取图片

2. 显示图片

3. 保存图片

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

5.彩色图像转灰度图

5.1用opencv将图片转成灰度图

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

6.顶帽变换

7.底帽变换

8.同态滤波


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

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()
绿色通道提取结果

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)
效果图

参考文:

(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博客

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到