掩膜

作者: 原上的小木屋 | 来源:发表于2020-06-06 15:15 被阅读0次

通过使用黑白二值图像将对应于黑色部分的原始图像的像素改变为黑色的操作被称为掩膜。

  • 举个例子,比如说要提取蓝色部分,就先创建这样的二进制图像,使得HSV色彩空间中180≤H≤260的位置的像素值设为1,并将其0和1反转之后与原始图像相乘。
  • 这使得可以在某种程度上将图像主体(从背景上)分离出来。
import cv2
import numpy as np
import matplotlib.pyplot as plt#照例导入三个基本库
# BGR -> HSV
def BGR2HSV(_img):#图像转BGR模式转HSV模式
    img = _img.copy() / 255.
    hsv = np.zeros_like(img, dtype=np.float32)
    # get max and min
    max_v = np.max(img, axis=2).copy()
    min_v = np.min(img, axis=2).copy()
    min_arg = np.argmin(img, axis=2)
    # H
    hsv[..., 0][np.where(max_v == min_v)]= 0
    ## if min == B
    ind = np.where(min_arg == 0)
    hsv[..., 0][ind] = 60 * (img[..., 1][ind] - img[..., 2][ind]) / (max_v[ind] - min_v[ind]) + 60
    ## if min == R
    ind = np.where(min_arg == 2)
    hsv[..., 0][ind] = 60 * (img[..., 0][ind] - img[..., 1][ind]) / (max_v[ind] - min_v[ind]) + 180
    ## if min == G
    ind = np.where(min_arg == 1)
    hsv[..., 0][ind] = 60 * (img[..., 2][ind] - img[..., 0][ind]) / (max_v[ind] - min_v[ind]) + 300
    # S
    hsv[..., 1] = max_v.copy() - min_v.copy()
    # V
    hsv[..., 2] = max_v.copy()
    return hsv
# make mask
def get_mask(hsv):#得到掩膜
    mask = np.zeros_like(hsv[..., 0])
    #mask[np.where((hsv > 180) & (hsv[0] < 260))] = 255
    mask[np.logical_and((hsv[..., 0] > 180), (hsv[..., 0] < 260))] = 1#提取蓝色区域
    return mask#返回掩膜图像
# masking
def masking(img, mask):
    mask = 1 - mask#反转
    out = img.copy()
    # mask [h, w] -> [h, w, channel]
    mask = np.tile(mask, [3, 1, 1]).transpose([1, 2, 0])#将单通道掩膜图像扩展到三通道掩膜图像
    out *= mask#原图与掩膜图像相乘,提取的蓝色区域变黑被隐藏
    return out
# Read image
img = cv2.imread("123.jpg").astype(np.float32)#读取原始图片
# RGB > HSV BGR转HSV
hsv = BGR2HSV(img)
# color tracking颜色追踪
mask = get_mask(hsv)#得到掩膜图像
# masking
out = masking(img, mask)#将掩模图像和原图一并传入
out = out.astype(np.uint8)
# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

掩膜(色彩追踪+形态学处理)

  • 上述代码处理的结果不够精细,背景也有部分的残留,可以在掩膜图像上运用开运算和闭运算,使得掩膜图片更加准确
import cv2
import numpy as np
import matplotlib.pyplot as plt#导入三个必要的库
# BGR -> HSV
def BGR2HSV(_img):#图像BGR转HSV模式
    img = _img.copy() / 255.
    hsv = np.zeros_like(img, dtype=np.float32)
    # get max and min
    max_v = np.max(img, axis=2).copy()
    min_v = np.min(img, axis=2).copy()
    min_arg = np.argmin(img, axis=2)
    # H
    hsv[..., 0][np.where(max_v == min_v)]= 0
    ## if min == B
    ind = np.where(min_arg == 0)
    hsv[..., 0][ind] = 60 * (img[..., 1][ind] - img[..., 2][ind]) / (max_v[ind] - min_v[ind]) + 60
    ## if min == R
    ind = np.where(min_arg == 2)
    hsv[..., 0][ind] = 60 * (img[..., 0][ind] - img[..., 1][ind]) / (max_v[ind] - min_v[ind]) + 180
    ## if min == G
    ind = np.where(min_arg == 1)
    hsv[..., 0][ind] = 60 * (img[..., 2][ind] - img[..., 0][ind]) / (max_v[ind] - min_v[ind]) + 300 
    # S
    hsv[..., 1] = max_v.copy() - min_v.copy()
    # V
    hsv[..., 2] = max_v.copy()
    return hsv
# make mask
def get_mask(hsv):#得到掩膜图像
    mask = np.zeros_like(hsv[..., 0])
    #mask[np.where((hsv > 180) & (hsv[0] < 260))] = 255
    mask[np.logical_and((hsv[..., 0] > 180), (hsv[..., 0] < 260))] = 1
    return mask
# masking
def masking(img, mask):#将掩膜图像叠加到原图中
    mask = 1 - mask
    out = img.copy()
    # mask [h, w] -> [h, w, channel]
    mask = np.tile(mask, [3, 1, 1]).transpose([1, 2, 0])
    out *= mask
    return out
# Erosion图片腐蚀
def Erode(img, Erode_time=1):
    H, W = img.shape
    out = img.copy()
    # kernel腐蚀核
    MF = np.array(((0, 1, 0),
                (1, 0, 1),
                (0, 1, 0)), dtype=np.int)
    # each erode
    for i in range(Erode_time):
        tmp = np.pad(out, (1, 1), 'edge')#扩充边缘
        # erode
        for y in range(1, H + 1):
            for x in range(1, W + 1):
                if np.sum(MF * tmp[y - 1 : y + 2 , x - 1 : x + 2]) < 1 * 4:#只有四邻域全为白,中央点才不会被改变,否则将中央点置0即黑
                    out[y - 1, x - 1] = 0#解释一下为啥这里是[y-1,x-1],还是因为tmp比out大一圈,tmp中央为[y,x],则out中央为[y-1,x-1]
    return out
# Dilation
def Dilate(img, Dil_time=1):
    H, W = img.shape
    # kernel
    MF = np.array(((0, 1, 0),
                (1, 0, 1),
                (0, 1, 0)), dtype=np.int)
    # each dilate time
    out = img.copy()
    for i in range(Dil_time):
        tmp = np.pad(out, (1, 1), 'edge')
        for y in range(1, H + 1):
            for x in range(1, W + 1):
                if np.sum(MF * tmp[y - 1 : y + 2, x - 1 : x + 2]) >= 1:
                    out[y - 1, x - 1] = 1
    return out
# Opening morphology一般形态学运算针对二值图像,刚好可以对应掩膜图像
def Morphology_Opening(img, time=1):#开运算,先腐蚀再膨胀
    out = Erode(img, Erode_time=time)
    out = Dilate(out, Dil_time=time)
    return out
# Closing morphology
def Morphology_Closing(img, time=1):#闭运算,先膨胀再腐蚀
    out = Dilate(img, Dil_time=time)
    out = Erode(out, Erode_time=time)
    return out
# Read image
img = cv2.imread("imori.jpg").astype(np.float32)
# RGB > HSV
hsv = BGR2HSV(img / 255.)
# color tracking
mask = get_mask(hsv)
# closing对掩膜图像先执行5次闭运算
mask = Morphology_Closing(mask, time=5)
# opening再对掩膜图像执行5次开运算
mask = Morphology_Opening(mask, time=5)
# masking
out = masking(img, mask)
out = out.astype(np.uint8)
# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像缩小与放大,其实这个我们在前面已经写过了,普适性会更强,下面这个代码只适用于方形图片

import cv2
import numpy as np
import matplotlib.pyplot as plt#导入三个常用的库
# Grayscale转灰度
def BGR2GRAY(img):
    # Grayscale
    gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
    return gray
# Bi-Linear interpolation双线性插值
def bl_interpolate(img, ax=1., ay=1.):
    if len(img.shape) > 2:
        H, W, C = img.shape
    else:
        H, W = img.shape
        C = 1
    aH = int(ay * H)#获取缩放之后的高度
    aW = int(ax * W)#获取缩放之后的宽度
    # get position of resized image获取调整大小后图像的位置
    y = np.arange(aH).repeat(aW).reshape(aW, -1)#沿着y方向
    x = np.tile(np.arange(aW), (aH, 1))#沿着x方向展开
    # get position of original position获取原始坐标位置
    y = (y / ay)
    x = (x / ax)
    ix = np.floor(x).astype(np.int)
    iy = np.floor(y).astype(np.int)
    ix = np.minimum(ix, W-2)#起始坐标
    iy = np.minimum(iy, H-2)#起始坐标
    # get distance
    dx = x - ix
    dy = y - iy
    if C > 1:
        dx = np.repeat(np.expand_dims(dx, axis=-1), C, axis=-1)
        dy = np.repeat(np.expand_dims(dy, axis=-1), C, axis=-1)
    # interpolation
    out = (1-dx) * (1-dy) * img[iy, ix] + dx * (1 - dy) * img[iy, ix+1] + (1 - dx) * dy * img[iy+1, ix] + dx * dy * img[iy+1, ix+1]
    out = np.clip(out, 0, 255)
    out = out.astype(np.uint8)
    return out
# Read image
img = cv2.imread("img11.png").astype(np.float)
gray = BGR2GRAY(img)
# Bilinear interpolation
out = bl_interpolate(gray.astype(np.float32), ax=0.1, ay=0.1)
# Bilinear interpolation
out = bl_interpolate(out, ax=10., ay=10.)
out = out.astype(np.uint8)
# Save result
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.imwrite("out.jpg", out)

相关文章

  • 掩膜

    通过使用黑白二值图像将对应于黑色部分的原始图像的像素改变为黑色的操作被称为掩膜。 举个例子,比如说要提取蓝色部分,...

  • 图像掩膜

    知识点 unsigned char 整数范围为0到255Mat.ptr (row) --返回row行的首地址,用法...

  • OpenCV:四、图像的基础操作

    前言 在上一章中描述了如何使用自己实现掩膜运算以及调用cv :: filter2D函数对图像进行掩膜运算矩阵的掩膜...

  • QR码设计(5)之mask

    转载请注明出处 1.1掩膜版的种类 QR码的掩膜版一共8种。他是在数据字和纠错字都在矩阵中填充完后,选择掩膜版类型...

  • 三 (3.1 core 模块) 矩阵掩膜与图像线性操作

    一、掩膜操作 1.1掩膜操作函数: 1.1.1filter2D 函数的定义如下: 1.1.2像素范围处理satur...

  • OPencv掩膜操作

    掩膜操作作用 1.提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不...

  • GEEMODIS数据质量波段应用

    MODIS质量控制数据应用 主要功能 使用MODIS的QA波段来进行云区掩膜,深海区域掩膜 代码 步骤分析 定义函...

  • opencv掩膜操作详解

    有时我们需要给一张图片添加logo,例如下图这样(图片来源): 1.掩膜操作思路 它的思想是: 先将彩色图像转换为...

  • OpenCV:绘制掩膜图像

    [注]: 1.vector中的点按顺序排列;2.使用drawContours获得图像掩膜.

  • 矩阵的掩膜操作

网友评论

      本文标题:掩膜

      本文链接:https://www.haomeiwen.com/subject/pkuazhtx.html