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

#はじめに
OpenCVによる画像処理の基礎を整理します。
100本ノックのように、毎日追加していきたいと思います。
#やりたいこと
マスクを使い、画像の論理演算を行います。必要ではない部分の除去などに応用可能です。
#マスクとは
光を遮る（Maskingする）意味として覚えてください。
マスクの機能は半導体の描画に使われるリソグラフィ工程を思い出すと、理解しやすいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/b8f30e33-c01b-7f63-c076-0601d6a4eb4d.png)

#実験に使う画像(オリジナル画像）
Lenaさんの写真を使います。サイズは512X512です。
![lena.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/9f9f2c5d-5028-1ab5-6e33-e2fcd2e92a63.png)

#マスク画像の準備

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

```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/40c217d6-0b4a-d95d-2453-17cfdb2af035.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の画像の上にマスクの白いパターンが重なるものになります。

```Python
img_OR = cv2.bitwise_or(img, mask)
```
![OR_screenshot_03.12.2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/fcc22009-4716-331c-172f-92fa745f8166.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のイメージが残ると思います。

```Python
img_AND = cv2.bitwise_and(img, mask)
```
![AND_screenshot_03.12.2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/8c0bba0c-753c-7f30-6a5c-f1cd905ad72f.png)

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

#全体コード

```Python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/37be0449-d38c-b16d-606a-e7bb62c817e6.png)