J'ai implémenté un filtre Sobel en utilisant OpenCV 3.2 sur Android. Notez que certaines parties ne pouvaient pas être attendues avec OpenCV de Java.
Windows 10 Home 64bit Android Studio 2.2.3 OpenCV 3.2
Nexus 5x (Android 7.1.1)
Voir ci-dessous Remarque sur l'introduction d'OpenCV pour Android dans Android Studio
Comme il est ennuyeux s'il ne s'agit que d'un filtre Sobel unidirectionnel, après l'avoir converti en échelle de gris, il est intentionnellement divisé en composants RVB et filtré dans les directions X et y pour chaque couleur pour obtenir la racine carrée moyenne carrée. Après cela, la valeur maximale parmi les valeurs des trois composants a été utilisée comme valeur de pixel finale.
Avec C ++ OpenCV
matC = matA +matB;
Vous pouvez écrire comme ça, mais vous ne pouvez pas le faire avec OpenCV de Java
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;
}
}
Implémenté en utilisant AsyncTask pour la commodité de l'interface graphique. Ici
apk Lien de l'apk construit Ici