關於新增水印,網上有一篇講的很清楚:
不過他的影象是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 ...