LoginSignup
3
4

More than 3 years have passed since last update.

[OpenCV] マスク操作 (OR, AND)

Posted at

はじめに

OpenCVによる画像処理の基礎を整理します。
100本ノックのように、毎日追加していきたいと思います。

やりたいこと

マスクを使い、画像の論理演算を行います。必要ではない部分の除去などに応用可能です。

マスクとは

光を遮る(Maskingする)意味として覚えてください。
マスクの機能は半導体の描画に使われるリソグラフィ工程を思い出すと、理解しやすいです。
image.png

実験に使う画像(オリジナル画像)

Lenaさんの写真を使います。サイズは512X512です。
lena.png

マスク画像の準備

512X512サイズの中に300X300サイズのマスクパターンを作ります。

width = 512
height=512

mask = np.zeros((width, height,3), np.uint8)
mask = cv2.rectangle(mask, (100,100),(400,400),(255,255,255), -1)

mask.png

論理演算

OR

A B A OR B
0 0 0
0 1 1
1 0 1
1 1 1

cv2.bitwise_or(original, mask)を使います。
単純にLenaの画像の上にマスクの白いパターンが重なるものになります。

img_OR = cv2.bitwise_or(img, mask)

OR_screenshot_03.12.2020.png

AND

A B A AND B
0 0 0
0 1 0
1 0 0
1 1 1

cv2.bitwise_and(original, mask)を使います。
マスクの開口部だけのLenaのイメージが残ると思います。

img_AND = cv2.bitwise_and(img, mask)

AND_screenshot_03.12.2020.png

まとめ

OpenCVのマスク操作を行いました。
マスクパターンをnumpyとopenCVの描画を利用して用意します。
その後、目的に応じてOR,ANDの論理演算を行います。

全体コード

import cv2
import numpy as np

#StackImage
def stackImages(scale, imgArray):
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver

# Original Image
img = cv2.imread('images/lena.png')

# Image Info

height, width, channels = img.shape[0:3]
print('height', height)
print('width', width)
print('channels', channels)


# Create a black image, a window

mask = np.zeros((width, height,3), np.uint8)
mask = cv2.rectangle(mask, (100,100),(400,400),(255,255,255), -1)

# OR
img_OR = cv2.bitwise_or(mask, img)
cv2.imshow('OR', img_OR)
cv2.waitKey(0)

# AND
img_AND = cv2.bitwise_and(img, mask)
cv2.imshow('AND', img_AND)
cv2.waitKey(0)

#描画

imgStack = stackImages(0.8, ([img,mask],
                            [img_OR,img_AND]))
cv2.imshow('Result', imgStack)
cv2.waitKey(0)

Result_screenshot_03.12.2020.png

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4