'Pictures taken from Kivy Camera on Android are dark

I've seen this question asked and answered several times but can never translate the proposed solutions into python code.

My Kivy App uses the Camera class to access the camera on an Android device and display the video inside my App. The resulting video and snapshots are very dark:

Here's a picture taken via the Camera App of the Android Tablet: picture via device camera

Here's the same picture taken from my app on the same Android device: enter image description here

This is the code I'm using to get Camera images:

main.py

class AndroidCamera(Camera):
    camera_resolution = (1920,1080)
    counter = 0

    def _camera_loaded(self, *largs):
        self.texture = Texture.create(size=self.camera_resolution, colorfmt='rgb')
        self.texture_size = list(self.texture.size)
        print(f'Created GL texture with size: {self.texture_size}')

    def on_tex(self, *l):
        if self._camera._buffer is None:
            return None
        frame = self.frame_from_buf()
        self.frame_to_screen(frame)
        super(AndroidCamera, self).on_tex(*l)

    def frame_from_buf(self):
        w, h = self.resolution
        frame = np.frombuffer(self._camera._buffer.tostring(), 'uint8').reshape((h + h // 2, w))    # TODO: try to understand why the frame size has nothing to do with the original resolution
        print(f'{frame.shape = }')
        frame_bgr = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_NV21)
        return frame_bgr

    def frame_to_screen(self, frame):
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        cv2.putText(frame_rgb, str(self.counter), (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
        self.counter += 1
        flipped = np.flip(frame_rgb, 0)
        buf = flipped.tostring()
        self.texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')

.kv file:

<PhotoScreen>
    GridLayout:
        canvas.before:
            Color:
                rgb: utils.get_color_from_hex("#ffffff")
            Rectangle:
                size: self.size
                pos: self.pos
        rows:2
        cols:1

        AndroidCamera:
            id: camera
            resolution:(1920,1080)
            allow_stretch: True
            play:True

One proposed solution i found was to set "CONTROL_CAPTURE_INTENT to CONTROL_CAPTURE_INTENT_VIDEO_RECORD." The user suggested to do something like:

request.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);

I have no experience in Java so my question is how would I do the above suggestion in python? Maybe using autoclass? How would that look like? Can I use my existing "AndroidCamera" class or do I have to completely re-write it?

I appreciate any support.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source