天天看點

C++實作的馬賽克類

    年前在一個網站上看到一個項目,對視訊流進行時時打碼處理,很有意思。本人利用過年時間寫了個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++;

}

}

 由于技術有限,現在打的馬賽克隻能是規則六邊形。希望牛人給些指點,如何将晶格變成不規則的。