0

I'm new to android studio and want to do face detection. The face detector code uses opencv and is written in python. I'm using chaquopy as the python SDK. When i run the app, the face is not detected. It is not showing any error also. Can someone help me out. Below is my MainActivity.java code:

public class MainActivity extends AppCompatActivity {

Button btn;
ImageView iv;


// now take bitmap and bitmap drawable to get image from image view
BitmapDrawable drawable;
Bitmap bitmap;
String imageString="";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn = (Button)findViewById(R.id.submit);
    iv = (ImageView)findViewById(R.id.image_view);


    if(!Python.isStarted())
        Python.start(new AndroidPlatform(this));

    final Python py = Python.getInstance();


    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // on click over button, get image from image view
            drawable = (BitmapDrawable)iv.getDrawable();
            bitmap = drawable.getBitmap();
            imageString = getStringImage(bitmap);
            // now in imagestring, we get encoded image string
            // now pass this input string to python script

            PyObject pyo = py.getModule("myscript");
            // calling the main function in python code and passing image string as parameter
            PyObject obj = pyo.callAttr("main", imageString);

            // obj will return value ie. our image string
            String str = obj.toString();
            // convert it to byte array
            byte data[] = android.util.Base64.decode(str, android.util.Base64.DEFAULT);
            // now convert it to bitmap
            Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);

            //now set this bitmap to imageview
            iv.setImageBitmap(bmp);


        }
    });
}

// function to convert this image into byte array and finally into base 64 string
private String getStringImage(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
    // store in byte array
    byte[] imageBytes = baos.toByteArray();
    // finally encode to string
    String encodedImage = android.util.Base64.encodeToString(imageBytes, android.util.Base64.DEFAULT); // Base64.DEFAULT
    return encodedImage;

}

}

and the below shown is my python script "myscript.py"

import numpy as np
import cv2
import io
from PIL import Image
import base64
import face_recognition

def main(data):
    decoded_data = base64.b64decode(data)
    np_data = np.fromString(decoded_data, np.uint8)
    img = cv2.imdecode(np_data, cv2.IMREAD_UNCHANGED)
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face_locations =  face_recognition.face_locations(img_gray)
    for(top,right,bottom,left) in face_locations:
        cv2.rectangle(img_rgb, (left,top),(right,bottom),(0,0,255),8)
    # convert this image to PIL
    pil_im = Image.fromarray(img_rgb)
    #convert this image to byte
    buff = io.BytesIO()
    pil_im.save(buff, format="PNG")
    #converting to base64
    img_str = base64.b64encode(buff.getvalue())
    return ""+str(img_str, 'utf-8')

My minSdkVersion is 16 and targetSdkVersion is 30. I'm not understanding what is the problem with this code. Can someone help me. Thanks in advance.

Ashna Eldho
  • 454
  • 1
  • 7
  • 22
  • What image is actually in the ImageView? Can you edit your question to show it? – mhsmith Jul 24 '21 at 11:50
  • Have you confirmed whether `face_recognition.face_locations` is returning anything? If not, try adding the line `print(face_locations)`, then searching for `python.stdout` in the [Logat](https://developer.android.com/studio/debug/am-logcat.html). This will let you know whether the problem is with the detection or with the output image. – mhsmith Jul 24 '21 at 11:53
  • I tried printing the face locations and searched in the logcat by entering python.stdout. But, it was not showing anything. When i removed that filter, i saw "2021-08-06 19:27:15.408 10753-10753/com.example.face_recognition_using_chaquopy I/Choreographer: Skipped 176 frames! The application may be doing too much work on its main thread." – Ashna Eldho Aug 06 '21 at 14:15
  • Do you mean it wasn't showing any stdout at all? If you added `print(face_locations)` immediately after calling `face_recognition.face_locations`, it should at least have shown it as an empty list. Are you sure you reinstalled the app after editing the code? Does it show in the logcat if you print something else like "Hello world"? – mhsmith Aug 07 '21 at 08:03
  • It is loading the image, but, when i click on “submit”, the app is closing. It should actually draw the bounding boxes when i click submit. Stdout command is not at all showing anything when i check the logcat. Print(“hello world”) also i tried. That is also not getting printed. – Ashna Eldho Aug 08 '21 at 10:06
  • Then it's probably crashing before getting as far as the `print`. See [this answer](https://stackoverflow.com/a/23353174) for how to find the stack trace, and if you still don't understand the cause, click the Edit link above and add the stack trace to your question. – mhsmith Aug 08 '21 at 16:02

0 Answers0