I implemented a Sobel filter on Android using OpenCV 3.2. Note that there were some parts that Java's OpenCV couldn't do as expected.
Windows 10 Home 64bit Android Studio 2.2.3 OpenCV 3.2
Nexus 5x (Android 7.1.1)
See below Note on introducing OpenCV for Android to Android Studio
Since it is boring if it is just a one-way Sobel filter, after converting it to grayscale, it is intentionally divided into RGB components and filtered in the X and y directions for each color to obtain the root mean square. After that, the maximum value among the values of the three components was used as the final pixel value.
With C ++ OpenCV
matC = matA +matB;
You can write like this, but you can't do it with Java's OpenCV
private Bitmap sobel(Bitmap bitmap) {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Mat mat = new Mat();
Mat matR = new Mat();
Mat matG = new Mat();
Mat matB = new Mat();
Utils.bitmapToMat(bitmap, mat);
Core.extractChannel(mat, matR, 0);
myFiltering(matR);
Core.extractChannel(mat, matG, 1);
myFiltering(matG);
Core.extractChannel(mat, matB, 2);
myFiltering(matB);
matMax3(matB, matG, matR, matB);
Utils.matToBitmap(matB, bitmap);
return bitmap;
}
private void myFiltering(Mat src){
Mat matX = new Mat();
Mat matY = new Mat();
Imgproc.GaussianBlur(src, src, new Size(3, 3), 0, 0);
Imgproc.Sobel(src, matX, src.depth(), 0, 1);
Imgproc.Sobel(src, matY, src.depth(), 1, 0);
matRMS(matX, matY, src);
}
private void matRMS(Mat src1, Mat src2, Mat dst) {
int size = (int) (src1.total() * src1.channels());
byte[] temp1 = new byte[size];
byte[] temp2 = new byte[size];
byte[] temp3 = new byte[size];
src1.get(0, 0, temp1);
src2.get(0, 0, temp2);
for (int i = 0; i < size; i++) {
temp3[i] = (byte)Math.sqrt((temp1[i] * temp1[i] + temp2[i] * temp2[i]) / 2);
}
dst.put(0, 0, temp3);
}
private void matMax3(Mat src1, Mat src2, Mat src3, Mat dst) {
int size = (int) (src1.total() * src1.channels());
byte[] temp1 = new byte[size];
byte[] temp2 = new byte[size];
byte[] temp3 = new byte[size];
byte[] temp4 = new byte[size];
src1.get(0, 0, temp1);
src2.get(0, 0, temp2);
src3.get(0, 0, temp3);
for (int i = 0; i < size; i++) {
temp4[i] = chooseBig(chooseBig(temp1[i], temp2[i]), temp3[i]);
}
dst.put(0, 0, temp4);
}
private byte chooseBig(byte a, byte b) {
if(b > a) {
return b;
}else {
return a;
}
}
Implemented using AsyncTask for GUI convenience. Here
apk Link of built apk Here
Recommended Posts