iOS 利用OpenCV實(shí)現(xiàn)圖片馬賽克效果

圖片馬賽克原理下圖所示:

圖片是由一個個像素組成,每個紅框表示一個像素,每一個像素都有一個RGBA的值,這里隨便用一寫字母表示其顏色值。

這里拿馬賽克大小為3個像素寬度舉例,如果設(shè)置為3個像素寬度的馬賽克處理,則每次手機(jī)會處理3*3共9個像素的矩陣,將這9個像素值處理成與矩陣第一個像素的值相等的像素值,然后重新填充矩陣像素值。每次從左到右,從上到下,以步長為3個像素,去處理每個3*3的像素矩陣,將這9個像素值處理成與矩陣第一個像素的值相等的像素值,直到將整個圖片的像素處理完成,生成馬賽克圖片。

下圖為原圖與處理后生成的二維碼圖片


原圖
馬賽克圖片


上代碼:

創(chuàng)建一個ImageUtils類,提供一個將原圖轉(zhuǎn)換成馬賽克圖片的方法

ImageUtils.h的代碼如下,需要導(dǎo)入OpenCV的一些文件,

#import <UIKit/UIKit.h>

//導(dǎo)入OpenCV框架

//核心頭文件

#import <opencv2/opencv.hpp>

//對ios支持

#import <opencv2/imgcodecs/ios.h>

//導(dǎo)入矩陣幫助類

#import <opencv2/highgui.hpp>

#import <opencv2/core/types.hpp>

//導(dǎo)入C++命名空間

using namespace cv;

@interface ImageUtils:NSObject

//定義方法:處理圖片

+(UIImage*)opencvImage:(UIImage*)image level:(int)level;

@end

因?yàn)橛玫搅薈++,所以ImageUtils.m也要改成ImageUtils.mm,ImageUtils.mm的實(shí)現(xiàn)如下

#import "ImageUtils.h"

@implementation ImageUtils

+(UIImage*)opencvImage:(UIImage*)image level:(int)level{

? ? ? //實(shí)現(xiàn)功能? ?

? ? ? //第一步:將iOS圖片->OpenCV圖片(Mat矩陣)? ??

? ? ? Mat mat_image_src;? ??

? ? ? UIImageToMat(image, mat_image_src);? ? ? ??

? ? ? //第二步:確定寬高? ??

? ? ? int width = mat_image_src.cols;? ??

? ? ? int height = mat_image_src.rows;? ? ? ??

? ? ? //圖片類型->進(jìn)行轉(zhuǎn)換? ??

? ? ? //在OpenCV里面? ??

? ? ? //坑隱藏? ??

? ? ? //支持->RGB處理? ??

? ? ? //圖片ARGB? ??

? ? ? //將ARGB->RGB? ??

? ? ? Mat mat_image_dst;? ??

? ? ? //一定要記得轉(zhuǎn)換類型

? ? ? cvtColor(mat_image_src, mat_image_dst, CV_RGBA2RGB, 3);? ? ? ??

? ? ? //為了不影響原始圖片? ??

? ? ? Mat mat_image_clone = mat_image_dst.clone();? ? ? ??

? ? ? ?//第三步:馬賽克處理? ?

? ? ? ?//分析馬賽克算法原理? ??

? ? ? ?//level = 3-> 3 * 3矩形? ??

? ? ? ?//動態(tài)的處理? ??

? ? ? ?int x = width - level;? ?

? ? ? ?int y = height - level;? ? ? ??

? ? ? ?for (int i = 0; i < y; i += level) {? ? ? ??

? ? ? ? ? ? ?for (int j = 0; j < x; j += level) {? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//創(chuàng)建一個矩形區(qū)域? ? ? ? ? ?

? ? ? ? ? ? ? ? ?Rect2i mosaicRect = Rect2i(j, i, level, level);? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//給填Rect2i區(qū)域->填充數(shù)據(jù)->原始數(shù)據(jù)? ? ? ? ? ??

? ? ? ? ? ? ? ? ?Mat roi = mat_image_dst(mosaicRect);? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//讓整個矩形區(qū)域顏色值保持一致? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//mat_image_clone.at(i, j)->像素點(diǎn)(顏色值組成->多個)->ARGB->數(shù)組? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//mat_image_clone.at(i, j)[0]->R值? ? ? ? ? ??

? ? ? ? ? ? ? ? ?//mat_image_clone.at(i, j)[1]->G值? ? ? ? ? ?

? ? ? ? ? ? ? ? ?//mat_image_clone.at(i, j)[2]->B值? ? ? ? ? ?

? ? ? ? ? ? ? ? Scalar scalar = Scalar( ? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mat_image_clone.at(i, j)[0],? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mat_image_clone.at(i, j)[1],? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mat_image_clone.at(i, j)[2]);

? ? ? ? ? ? ? ? ?//將處理好矩形區(qū)域->數(shù)據(jù)->拷貝到圖片上面去->修改后的數(shù)據(jù)

? ? ? ? ? ? ? ? ?//CV_8UC3解釋一下->后面也會講到

? ? ? ? ? ? ? ? ?//CV_:表示框架命名空間

? ? ? ? ? ? ? ? ?//8表示:32位色->ARGB->8位 = 1字節(jié) -> 4個字節(jié)

? ? ? ? ? ? ? ? ?//U分析

? ? ? ? ? ? ? ? ?//兩種類型:有符號類型(Sign->有正負(fù)->簡寫"S")、無符號類型(Unsign->正數(shù)->"U")

? ? ? ? ? ? ? ? ?//無符號類型:0-255(通常情況)

? ? ? ? ? ? ? ? ?//有符號類型:-128-127

? ? ? ? ? ? ? ? ?//C分析:char類型

? ? ? ? ? ? ? ? ?//3表示:3個通道->RGB

? ? ? ? ? ? ? ? ?Mat roiCopy = Mat(mosaicRect.size(), CV_8UC3, scalar);

? ? ? ? ? ? ? ? ?roiCopy.copyTo(roi);

? ? ? ? ? }

? ? ?}

? ? //第四步:將OpenCV圖片->iOS圖片

? ? return MatToUIImage(mat_image_dst);

}

@end


調(diào)用ImageUtils相應(yīng)的代碼:

#import "ImageUtils.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad {

? ? ? ? [super viewDidLoad];

}

//正常圖片

- (IBAction)clickNormal:(id)sender {

? ? ? ? _imageView.image = [UIImage imageNamed:@"girl.jpeg"];

}

//馬賽克圖片

- (IBAction)clickMosaic:(id)sender {

? ? ? ? _imageView.image = [ImageUtils opencvImage:_imageView.image level:20];

}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容