OpenCV探索之路(十三):詳解掩膜mask

在OpenCV中咱們常常會遇到一個名字:Mask(掩膜)。不少函數都使用到它,那麼這個Mask到底什麼呢?ios

一開始我接觸到Mask這個東西時,我還真是一頭霧水啊,也對沒法理解Mask到底有什麼用。通過查閱大量資料後,也對Mask有一點本身的理解了,下面就說說個人理解。函數

好比我要對一幅圖進行摳圖操做,這就要用到Mask了,那我就以摳圖爲例,解釋Mask在裏面的做用。ui

先上程序,再一句一句剖析。spa

該程序的功能就是摳出指定區域。code

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main()
{
    Mat image, mask;
    Rect r1(100, 100, 250, 300);
    Mat img1, img2, img3, img4;
    image = imread("lol17.jpg");
    mask = Mat::zeros(image.size(), CV_8UC1);
    mask(r1).setTo(255);
    img1 = image(r1);
    image.copyTo(img2, mask);

    image.copyTo(img3);
    img3.setTo(0, mask);


    imshow("Image sequence", image);
    imshow("img1", img1);
    imshow("img2", img2);
    imshow("img3", img3);
    imshow("mask", mask);

    waitKey();
    return 0;
}

原始圖
blog

注意程序中的這兩句關於Mask的操做。it

mask = Mat::zeros(image.size(), CV_8UC1); 
mask(r1).setTo(255);  //r1是設置好的感興趣區域

解釋一下上面兩句的操做。io

  • 第一步創建與原圖同樣大小的mask圖像,並將全部像素初始化爲0,所以全圖成了一張全黑色圖。
  • 第二步將mask圖中的r1區域的全部像素值設置爲255,也就是整個r1區域變成了白色。

這樣就能獲得Mask圖像了。
opencv

注意這句,哪一個圖像拷貝到哪一個圖像?gui

image.copyTo(img2, mask);

固然是原始圖image拷貝到目的圖img2上啦。
其實拷貝的動做完整版本是這樣的:

原圖(image)與掩膜(mask)進行與運算後獲得告終果圖(img2)。

何爲圖與掩膜的與運算?

其實就是原圖中的每一個像素和掩膜中的每一個對應像素進行與運算。好比1 & 1 = 1;1 & 0 = 0;

好比一個3 * 3的圖像與3 * 3的掩膜進行運算,獲得的結果圖像就是:

說白了,mask就是位圖啊,來選擇哪一個像素容許拷貝,哪一個像素不容許拷貝。若是mask像素的值是非0的,我就拷貝它,不然不拷貝。

由於咱們上面獲得的mask中,感興趣的區域是白色的,代表感興趣區域的像素都是非0,而非感興趣區域都是黑色,代表那些區域的像素都是0。一旦原圖與mask圖進行與運算後,獲得的結果圖只留下原始圖感興趣區域的圖像了。也正以下圖所示。

image.copyTo(img2, mask);

下面兩句代碼所作的事情跟上面的差很少,首先將原始圖image拷貝一份給img3,而後img3將mask白色區域設置爲0(黑色),比如若是mask中像素非0的,我就把我圖像對應的那個點的像素值設置爲0,不然啥也不作。僞代碼是if mask(i,j)>0 then img3(i,j)=0。

image.copyTo(img3);
img3.setTo(0, mask);

若是想要直接摳出目標區域,直接這樣寫就OK了:

img1 = image(r1);

相關文章
相關標籤/搜索