年前在一個網站上看到一個項目,對視訊流進行時時打碼處理,很有意思。本人利用過年時間寫了個C++實作的馬賽克類,娛樂一下。
環境:vs2008 + opencv2.0
頭檔案Mosaic.h
//
//功能:對圖像進行馬賽克處理
//作者:enjoy
//時間:2010年02月16日
//版本:alpha 1.0.1
//改進:對邊緣處處理失效的問題
// 進行了修改
//
#include "cxcore.h"
class Mosaic
{
private:
int threshold[90][90];
public:
Mosaic(void);
//生成半徑為r的掩模矩陣
//
Mosaic(int r);
~Mosaic(void);
//馬賽克處理
//原始圖像src 處理後的圖像dst 掩模半徑radius
//
void maskon(IplImage * src, IplImage * dst, int radius);
};
CPP檔案Mosaic.cpp
//
//功能:對圖像進行馬賽克處理
//作者:enjoy
//時間:2010年02月16日
//版本:alpha 1.0.1
//改進:對邊緣處處理失效的問題
// 進行了修改
//
#include "StdAfx.h"
#include "Mosaic.h"
Mosaic::Mosaic(void)
{
}
//生成半徑為r的掩模矩陣
//
Mosaic::Mosaic(int r)
{
//掩模矩陣的半高
//
int h_t = (int)(3 * (r - 1) / 2);
//掩模矩陣的半寬
//
int w_t = r - 1;
//掩模矩陣初始化
//
for (int i = - h_t; i<= h_t; i++)
for (int j = - w_t; j <= w_t; j++)
threshold[i + h_t][j + w_t] = 0;
//生成掩模矩陣
//
for (int i = - h_t; i<= h_t; i++)
{
if (i < - h_t + r)
{
for (int j = - w_t; j <= w_t; j++)
if (j >= (- h_t - i) && j <= (h_t + i))
threshold[i + h_t][j + w_t] = 1;
}
else
if (i > h_t - r)
{
for (int j = - w_t; j <= w_t; j++)
if (j >= (- h_t + i) && j <= (h_t - i))
threshold[i + h_t][j + w_t] = 1;
}
else
{
for (int j = - w_t; j <= w_t; j++)
threshold[i + h_t][j + w_t] = 1;
}
}
}
Mosaic::~Mosaic(void)
{
}
//馬賽克處理
//原始圖像src 處理後的圖像dst 掩模半徑radius
//
void Mosaic::maskon(IplImage *src, IplImage *dst, int r)
{
//圖像高度
//
int h = src->height;
//圖像寬度
//
int w = src->width;
int thr = 0;
int thg = 0;
int thb = 0;
//馬賽克晶格行數
//
int row = 0;
//馬賽克晶格列數
//
int col = 0;
int flag_row = 1;
int flag_col = 1;
//晶格行數對應圖像行數
//
int cor_row = 0;
//晶格列數對應圖像列數
//
int cor_col = 0;
//掩模矩陣的半高
//
int h_t = (int)(3 * (r - 1) / 2);
//掩模矩陣的半寬
//
int w_t = r - 1;
//行坐标偏移
//
int cor_shift_row = 0;
//列坐标偏移
//
int cor_shift_col = 0;
while (flag_row)
{
cor_row = (2 * r - 1) * row - (int)((r - 1) / 2);
if (cor_row >= h)
flag_row = 0;
if (cor_row < 0)
cor_shift_row = - cor_row;
else if (cor_row >= h)
cor_shift_row = h - cor_row - 1;
else
cor_shift_row = 0;
uchar * ptr_s = (uchar *)(src->imageData + (cor_row + cor_shift_row) * src->widthStep);
flag_col = 1;
col = 0;
while (flag_col)
{
if (row % 2 == 1)
cor_col = 2 * r * col - r;
else
cor_col = 2 * r * col;
if (cor_col >= w)
flag_col = 0;
if (cor_col < 0)
cor_shift_col = - cor_col;
else if (cor_col >= w)
cor_shift_col = w - cor_col - 1;
else
cor_shift_col = 0;
//得到晶格矩陣中心對應圖像像素點的
//RGB顔色
//
thb = ptr_s[3 * (cor_col + cor_shift_col)];
thg = ptr_s[3 * (cor_col + cor_shift_col) + 1];
thr = ptr_s[3 * (cor_col + cor_shift_col) + 2];
//掩模矩陣值為1時,圖像對應區域像素操作
//
for (int i = - h_t; i <= h_t; i++)
{
if ((cor_row + i) >= h || (cor_row + i) < 0)
continue;
uchar * ptr_d = (uchar *)(dst->imageData + (cor_row + i) * dst->widthStep);
for (int j = - w_t; j <= w_t; j++)
{
if ((cor_col + j) >= w || (cor_col + j) < 0)
continue;
if (threshold[i + h_t][j + w_t])
{
ptr_d[3 * (cor_col + j)] = thb;
ptr_d[3 * (cor_col + j) + 1] = thg;
ptr_d[3 * (cor_col + j) + 2] = thr;
}
}
}
col++;
}
row++;
}
}
由于技術有限,現在打的馬賽克隻能是規則六邊形。希望牛人給些指點,如何将晶格變成不規則的。