OpenCV學習(三)使用mask新增水印

2021-06-15 04:32:19 字數 1737 閱讀 2649

關於新增水印,網上有一篇講的很清楚:

不過他的影象是png格式的,本身是透明背景,本篇將採用普通jpg格式做水印。

第一步,分析 copyto 函式:

//! copies those matrix elements to "m" that are marked with non-zero mask elements.

void copyto( outputarray m, inputarray mask ) const;

關注mask引數。要去掉水印的背景,需要使用mask,對不想修改的部分不做修改(上面的注釋很清楚,就是說只對非0的位置做操作)。

那麼如何構造這個mask?那麼我需要對water_mark影象做二值化,生成乙個黑白的mask,其中想留下的水印部分是非0(白色255),需要疊加操作;背景是0(黑色0),不需要疊加操作。

我的影象是白色背景的(用mspaint繪製:) )

首先,通過 cvtcolor 把 water_mark 影象變成灰度圖 grey:

mat     gray(water_mark);

cvtcolor(gray, gray, cv_rgb2gray);

再通過二值化函式 threshold 把灰度圖 gray 轉化為黑白圖 mask,其中 最後乙個引數 type 要看情況而定,我這裡是 cv_thresh_binary_inv,表明做乙個反轉。(如果不反轉一下,嘿嘿,那就成了疊加背景和鏤空水印了。)

mat     mask(gray);

cv::threshold(gray, mask, 128, 255, cv_thresh_binary_inv);

關於門限型別的定義 opencv解釋的很清楚:

/* threshold types */

enum

;效果圖:

這個是疊加式(覆蓋式)水印,即直接覆蓋掉原來的影象,如果想使用半透明的水印,我這裡採用了乙個比較土的辦法,構造了乙個彩色的 color_mask,跟 water_mark 做「與」操作,使 water_mark 背景部分畫素值rgb分量全部變成0,再跟 image 做 addweighted 操作,即可。

color_mask 的構造過程:通過 split 對 water_mark 按通道分割成rgb三個單通道影象,每個影象都拷貝成單通道的 mask,然後重新合併 merge成彩色蒙版。

mat color_mask;

std::vectorplanes;

split(water_mark, planes);

std::vector::iterator it = planes.begin();

for(; it != planes.end(); ++it)

merge(planes, color_mask);

cv::bitwise_and(water_mark, color_mask, water_mark);

addweighted(roi, 1.0, water_mark, 0.5, 0, roi); //alpha add

效果圖:

OpenCV系列 詳解掩膜mask

在opencv中我們經常會遇到乙個名字 mask 掩膜 很多函式都使用到它,那麼這個mask到底什麼呢?一開始我接觸到mask這個東西時,我還真是一頭霧水啊,也對無法理解mask到底有什麼用。經過查閱大量資料後,也對mask有一點自己的理解了,下面就說說我的理解。比如我要對一幅圖進行摳圖操作,這就要...

《學習OpenCV》 初探OpenCV(三)

引數1 影象 引數2 矩形的乙個頂點 引數3 矩形另乙個頂點 引數4 線條顏色 rgb 或亮度 灰度影象 可省略 有過載函式 引數5 線條粗細程度,取cv filled表填充色彩矩陣 引數6 線條型別 引數7 座標點的小數 cvmat cvcreatemat int rows,int cols,in...

opencv 提取多邊形mask區域

最近在專案中需要提取多邊形區域,並傳入到運算元中計算,故記錄一下對多邊形mask區域的提取方法。include using namespace cv int main 關鍵函式為 fillpoly,該函式提供兩種呼叫介面,分別如下 void fillpoly mat img,const point ...