Ich habe einen Sobel-Filter mit OpenCV 3.2 unter Android implementiert. Beachten Sie, dass es einige Teile gab, die mit Javas OpenCV nicht zu erwarten waren.
Windows 10 Home 64bit Android Studio 2.2.3 OpenCV 3.2
Nexus 5x (Android 7.1.1)
Siehe unten Hinweis zur Einführung von OpenCV für Android in Android Studio
Da es langweilig ist, wenn es sich nur um ein Einweg-Sobel-Filter handelt, wird es nach der Konvertierung in Graustufen absichtlich in RGB-Komponenten unterteilt und für jede Farbe in X- und Y-Richtung gefiltert, um die quadratische durchschnittliche Quadratwurzel zu erhalten. Danach wurde der Maximalwert unter den Werten der drei Komponenten als endgültiger Pixelwert verwendet.
Mit C ++ OpenCV
matC = matA +matB;
Sie können so schreiben, aber mit Javas OpenCV nicht
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;
}
}
Implementiert mit AsyncTask für die Bequemlichkeit der GUI. Hier
apk Link der gebauten apk Hier
Recommended Posts