opencv-圖片馬賽克處理

weixin_33861800發表於2017-10-24
2262256-cad862ddd28a62f2.png

實現圖片馬賽的方式很多,為什麼這裡要單獨提opencv?

先看簡介:

OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,可以執行在Linux、Windows、Android和Mac OS作業系統上。它輕量級而且高效——由一系列 C 函式和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的介面,實現了影象處理和計算機視覺方面的很多通用演算法。
OpenCV用C++語言編寫,它的主要介面也是C++語言,但是依然保留了大量的C語言介面。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的介面。這些語言的API介面函式可以通過線上文件獲得。如今也提供對於C#,Ch, Ruby的支援。

知道了嗎?沒錯,c/c++編寫,可以支援多個平臺開發。
先下載對應的opencv版本,官網不翻牆進不去,網上找最新版本比較費時間,博主福利:opencv下載

2262256-0d75545d54a106d3.png
馬賽克原理:將指定區域的畫素點值,全部改為左上角第一個點的畫素點值

iOS平臺用法

  • 匯入opencv2.framework
  • 匯入標頭檔案
//核心標頭檔案 hpp c++ 檔案字尾
#import <opencv2/opencv.hpp>
//對iOS支援
#import <opencv2/imgcodecs/ios.h>
//匯入矩陣幫助類
#import <opencv2/highgui.hpp>
#import <opencv2/core/types.hpp>

//匯入C++名稱空間
using namespace cv;
  • 注意事項
    • iOS裡面opencv只支援RGB圖片處理,所以需要將ARGB圖片轉為RGB (ARGB是一種色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常見於32位點陣圖的儲存結構。)
    • opencv使用c++編寫的介面,所以實現檔案字尾需要改為.mm
    • CV_8UC3名稱解釋(以後遇到類似的都可以如此理解)
      • CV_:表示框架名稱空間
      • 8表示:32位色->ARGB->8位 = 1位元組 -> 4個位元組
      • 兩種型別:有符號型別(Sign->有正負->簡寫"S")、無符號型別(Unsign->正數->"U")。無符號型別:0-255(通常情況)。有符號型別:-128-127
      • C分析:char型別
      • 3表示:3個通道->RGB
  • 核心實現程式碼
+(UIImage*)opencvImage:(UIImage*)image level:(int)level{
        //實現功能
        //第一步:將iOS圖片->OpenCV圖片(Mat矩陣)
        Mat mat_image_src;
        UIImageToMat(image, mat_image_src);
        
        //第二步:確定寬高
        int width = mat_image_src.cols;
        int height = mat_image_src.rows;
        

        //圖片型別->進行轉換
        //在OpenCV裡面只支援RGB處理將ARGB圖片->RGB
        Mat mat_image_dst;
        cvtColor(mat_image_src, mat_image_dst, CV_RGBA2RGB, 3);
        
        //研究OpenCV時候,如何發現巨坑?
        //觀察規律
        //看到了OpenCV官方網站->每次進行影象處理時候,規律->每一次都會呼叫cvtColor保持一致(RGB)
        //所以:每一次你在進行轉換的時候,一定要記得轉換型別
        
        //為了不影響原始圖片
        Mat mat_image_clone = mat_image_dst.clone();
        
        //第三步:馬賽克處理
        //分析馬賽克演算法原理
        //level = 3-> 3 * 3矩形
        //動態的處理
        int x = width - level;
        int y = height - level;
        
        for (int i = 0; i < y; i += level) {
            for (int j = 0; j < x; j += level) {
                //建立一個矩形區域
                Rect2i mosaicRect = Rect2i(j, i, level, level);
                
                //給填Rect2i區域->填充資料->原始資料
                Mat roi = mat_image_dst(mosaicRect);
                
                //讓整個矩形區域顏色值保持一致
                //mat_image_clone.at<Vec3b>(i, j)->畫素點(顏色值組成->多個)->ARGB->陣列
                //mat_image_clone.at<Vec3b>(i, j)[0]->R值
                //mat_image_clone.at<Vec3b>(i, j)[1]->G值
                //mat_image_clone.at<Vec3b>(i, j)[2]->B值
                Scalar scalar = Scalar(
                       mat_image_clone.at<Vec3b>(i, j)[0],
                       mat_image_clone.at<Vec3b>(i, j)[1],
                       mat_image_clone.at<Vec3b>(i, j)[2]);
                
                //將處理好矩形區域->資料->拷貝到圖片上面去->修改後的資料
                //CV_8UC3解釋一下->後面也會講到
                //CV_:表示框架名稱空間
                //8表示:32位色->ARGB->8位 = 1位元組 -> 4個位元組
                //U分析
                //兩種型別:有符號型別(Sign->有正負->簡寫"S")、無符號型別(Unsign->正數->"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);
    }

一如既往,有部落格必demo

相關文章