1. 程式人生 > >Android OpenCV新增影象效果

Android OpenCV新增影象效果

    本文重點介紹OpenCV獲取到的幀影象處理,關於OpenCV中獲取開啟相機,及相機緩衝幀的方法請參考     首先我們需要從相機緩衝幀中獲取到RGBA矩陣:
Mat rgba = inputFrame.rgba();
    處理畫素的方法採用Filter介面的方式,Filter介面程式碼如下:
public interface Filter {
public abstract void apply(Mat src, Mat dst);
}
    介面中定義了apply方法,接收一個原始資料的Mat物件,和一個結果資料的Mat物件。緊接著,定義一個NoneFilter:
public class 
NoneFilter implements Filter {

@Override
public void apply(Mat src, Mat dst) {
// Do nothing.
}
}
    NoneFilter類的apply()方法什麼也沒做,這個Filter的功能就是不對資料做任何處理。 接下來看我們具體的新增影象效果的Filter 1.混合顏色通道: 1.RecolorRCFilter:
public class RecolorRCFilter implements Filter {

private ArrayList<Mat> mChannels = new ArrayList<Mat>(
4);
@Override
public void apply(Mat src, Mat dst) {
Core.split(src, mChannels);
Mat g = mChannels.get(1);
Mat b = mChannels.get(2);
// dst.g = 0.5 * src.g + 0.5 * src.b
Core.addWeighted(g, 0.5, b, 0.5, 0.0, g);
// dst.b = dst.g
mChannels.set(2, g);
Core.merge(mChannels, dst);
}
}
       該濾鏡將綠色和藍色轉換為青色,並保留有限的紅色和青色調色盤。該濾鏡可模擬早期電影和計算機遊戲顯示效果。該濾鏡主要方法介紹:
       Core.split(Mat m, List<Mat> mv)方法負責分離通道,該方法對應的引數為源矩陣和目標矩陣列表。來自原矩陣的各個通道被複制至目標列表中的獨立通道的矩陣中。        Core.addWeight(Mat src1, double alpha, Mat src2, double beta, double gramma, Mat dst)方法可用於計算兩個通道的加權平均值。前4個引數分別表示為權值和源矩陣;第5個引數表示常數,並加入到計算結果中;最後一個引數為目標矩陣。        Core.merge(List<Mat> mv, Mat m)方法可視為Core.split方法的逆制方法,可將獨立通道重新生成多通道影象。 2、RecolorRGVFilter:       該Filter與RecolorRCFilter基本相同,只是將addWeighted操作換成了min操作,不同處的程式碼為:
Core.min(b, r, b);
Core.min(b, g, b);
       Core.min(Mat src1, Mat src2, Mat dst)方法接收一組源矩陣和目標矩陣,執行逐個元素的min操作,min操作可以降低輸出通道的飽和度。
       該濾鏡將降低藍色的飽和度,並遺留有限的紅色、綠色、和白色調色盤。該濾鏡模擬了早期電影和計算機遊戲的顯示效果。 3、RecolorRMVFilter: 該Filter與RecolorRCFilter基本相同,只是將addWeighted操作換成了max操作,不同處的程式碼為:
Core.max(b, r, b);
Core.max(b, g, b);
       Core.max(Mat src1, Mat src2, Mat dst)接收一組源矩陣和目標矩陣,執行逐個元素的max操作。max操作可以降低輸出通道互補色的飽和度。         該濾鏡將降低黃色的飽和度,並遺留有限的青色、洋紅、和白色調色盤。該濾鏡模擬了20世紀80年代計算機遊戲的效果。 2.使用卷積過濾處理鄰接畫素         在卷積濾鏡中,各個輸出畫素的通道值為鄰接輸入畫素對應通道值得加權平均的結果。二話不說,先上程式碼:
public class StrokeEdgesFilter implements Filter {

private Mat mKernel = new MatOfInt(
0, 0, 1, 0, 0,
0, 1, 2, 1, 0,
1, 2, -16, 2, 1,
0, 1, 2, 1, 0,
0, 0, 1, 0, 0
);
private Mat mEdges = new Mat();
@Override
public void apply(Mat src, Mat dst) {
Imgproc.filter2D(src, mEdges, -1, mKernel);
Core.bitwise_not(mEdges, mEdges);
Core.multiply(src, mEdges, dst, 1.0 / 255.0);
}
}
Core.filter2D(Mat src, Mat dst, int depth, double delta)方法可以自定義卷積矩陣,depth引數可以為下面內容之一:
  1.   -1:與資料來源具有相同的型別;
  2.  CvType.CV_16S:16位有符號整數
  3.  CvType.CV_32F:32位浮點數
  4.  CvType.CV_64S:64位浮點數
Core.bitwise_not(Mat src, Mat dst):方法逆置影象的亮度和顏色,即白色變為黑色,紅色變為青色等。 Core.multipy(Mat src1, Mat src2, Mat dst, double scale):該方法通過在對應資料值之間執行乘法運算,進而混合一組影象。最終結果可以通過scale引數進行縮放計算。        通過該濾鏡實現了黑色邊框效果。卷積濾鏡還可以實現腐蝕、羽化等多種效果,這些效果將在後續文章中介紹。         最後在CameraActivity的的onCameraFrame方法中新增濾鏡處理程式碼:
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
// Apply the active filters.
mCurveFilters[mCurveFilterIndex].apply(rgba, rgba);
mMixerFilters[mMixerFilterIndex].apply(rgba, rgba);
mConvolutionFilters[mConvolutionFilterIndex].apply(rgba, rgba);
return rgba;
}
       本例項中,點選ActionBar的程式碼可實現濾鏡的切換,獲得不同的圖片效果,執行效果如圖所以:
專案Github地址:https://github.com/BruceT2010/OpenCV4AndroidSecondSight