No OpenCV, muitas vezes encontramos um nome: Mask (máscara). Muitas funções a usam, então o que exatamente é essa máscara? Quando entrei em contato com a Máscara pela primeira vez, fiquei muito confuso e não conseguia entender para que servia a Máscara. Depois de consultar muitas informações, também entendi um pouco do Mask. Deixe-me falar sobre meu entendimento abaixo.
Por exemplo, se eu quiser recortar uma imagem, preciso usar o Mask, então usarei o recorte como exemplo para explicar o papel do Mask nele. Vá primeiro ao programa e depois analise-o frase por frase. A função deste programa é cortar a área especificada.
#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;
}
A imagem original:
Preste atenção nas duas frases do programa sobre o funcionamento do Mask.
mask = Mat::zeros(image.size(), CV_8UC1);
mask(r1).setTo(255); //r1是设置好的感兴趣区域
Explique o funcionamento das duas frases acima.
- O primeiro passo é criar uma imagem de máscara do mesmo tamanho da imagem original e inicializar todos os pixels em 0, para que toda a imagem se torne uma imagem completamente preta.
- Na segunda etapa, todos os valores de pixel na área r1 no mapa de máscara são definidos como 255, ou seja, toda a área r1 fica branca.
Desta forma, a imagem Mask pode ser obtida.
Preste atenção nesta frase, qual imagem é copiada para qual imagem?
image.copyTo(img2, mask);
Obviamente, a imagem da imagem original é copiada para a imagem de destino img2.
Na verdade, a versão completa da ação de cópia é a seguinte:
A imagem original (imagem) e a máscara (máscara) são conectadas para obter a imagem resultante (img2).
Qual é a operação AND de um gráfico e uma máscara?
Na verdade, cada pixel na imagem original e cada pixel correspondente na máscara são ANDed. Por exemplo 1 & 1 = 1; 1 & 0 = 0;
Por exemplo, uma imagem 3 * 3 é calculada com uma máscara 3 * 3 e a imagem resultante é:
Para ser franco, a máscara é um bitmap, para escolher quais pixels podem ser copiados e quais pixels não podem ser copiados. Se o valor do pixel da máscara for diferente de zero, eu copio, senão não copio.
Porque na máscara que obtivemos acima, a região de interesse é branca, indicando que os pixels na região de interesse são todos diferentes de zero, e as regiões sem interesse são todas pretas, indicando que os pixels nessas regiões são todos 0 . Depois que a imagem original e a imagem da máscara são conectadas, a imagem resultante deixa apenas a imagem da região de interesse na imagem original. Também como mostrado abaixo.
image.copyTo(img2, mask);
As duas linhas de código a seguir fazem o mesmo que acima. Primeiro, copie a imagem da imagem original para img3 e, em seguida, img3 define a área branca da máscara como 0 (preto). Por exemplo, se os pixels na máscara não forem 0, definirei meu O valor do pixel do ponto correspondente à imagem será definido como 0, caso contrário, nada será feito. O pseudocódigo é se mask(i,j)>0 então img3(i,j)=0.
image.copyTo(img3);
img3.setTo(0, mask);
Se você deseja extrair diretamente a área de destino, basta escrever assim:
img1 = image(r1);