0

I want to use Camera to capture photos and scan barcode in my Android app. I added it in kv:

<CameraForm>:
    FloatLayout:
        Camera:
            id: camera
            size_hint: (1, 0.8)
            pos_hint: {"center_x": 0.5, "top": 0.95}
            canvas.before:
                PushMatrix
                Rotate:
                    angle: -90 if app.isAndroid() else 0
                    origin: self.center
            canvas.after:
                PopMatrix

        MDRaisedButton:
            text: "Capture"
            size_hint: (None, None)
            height: "40dp"
            pos_hint: {"x": 0.2, "top": 0.1}
            on_press: root.capturePhoto()

And python code:

class CameraForm(Screen):
    def __init__(self, *args, **kwargs):
        super(CameraForm, self).__init__(*args, **kwargs)
        self.fileName = None
        self.camera = None

    def initCamera(self):
        self.camera = self.ids.camera
        self.camera.resolution = (720, 480)
        self.camera.keep_ratio = True
        self.camera.play = True
        self.camera.allow_stretch = True

    def on_enter(self, *args):
        self.initCamera()

    def capturePhoto(self):
        imgTime = time.strftime("%Y%m%d_%H%M%S")
        self.fileName = MDApp.get_running_app().imagePath + "IMG_{}.png".format(imgTime)  # store image file
        self.camera.export_to_png(self.fileName)
        msgBox = MessageBox()
        msgBox.showMsg("Information", "Image has been successfully captured!", "OK", False)

The similar code I have for Camera to scan Barcode. The problem is when I try to switch from Camera to Barcode camera then I got the following issues:

[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (1113) SourceReaderCB::OnReadSample videoio(MSMF): OnReadSample() is called with error status: -1072873821
[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (1125) SourceReaderCB::OnReadSample videoio(MSMF): async ReadSample() call is failed with error status: -1072873821
[ WARN:1] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (1159) CvCapture_MSMF::grabFrame videoio(MSMF): can't grab frame. Error: -1072873821
[ERROR  ] [OpenCV      ] Couldn't get image from Camera
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\kivy\core\camera\camera_opencv.py", line 144, in _update
    self._buffer = frame.imageData
AttributeError: 'NoneType' object has no attribute 'imageData'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\kivy\core\camera\camera_opencv.py", line 148, in _update
    self._buffer = frame.reshape(-1)
AttributeError: 'NoneType' object has no attribute 'reshape'
[ WARN:1] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (1159) CvCapture_MSMF::grabFrame videoio(MSMF): can't grab frame. Error: -2147483638
[ERROR  ] [OpenCV      ] Couldn't get image from Camera
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\kivy\core\camera\camera_opencv.py", line 144, in _update
    self._buffer = frame.imageData
AttributeError: 'NoneType' object has no attribute 'imageData'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\kivy\core\camera\camera_opencv.py", line 148, in _update
    self._buffer = frame.reshape(-1)
AttributeError: 'NoneType' object has no attribute 'reshape'

And the app crashes. So, I think it needs to free the Camera resources.

def on_leave(self, *args):
    self.camera.stop()

When I try to leave camera screen it reports error:

AttributeError: 'Camera' object has no attribute 'stop'

But from the kivy docs: https://kivy.org/doc/stable/api-kivy.core.camera.html#kivy.core.camera.CameraBase.stop

stop() Added in 1.0.0 Release the camera

So, why stop() is not available for Camera? How to free the Camera resources? Thank you for the help.

Hunter91151
  • 457
  • 2
  • 11
  • i had the same problem. The solution for me in this question https://stackoverflow.com/questions/61980957/kivy-camera-on-multiple-screen/61987939#61987939 – Angelo Gabriel Abrita May 28 '20 at 00:39

1 Answers1

1

The kivy.core.camera.CameraBase class has a stop() method but the Camera widget (in your .kv file) is an instance of the kivy.uix.camera.Camera class and it does not have stop() method.

If you want to stop the camera, you can use the play property of Camera. Camera's doc.

Otherwise you can use self.camera._camera to directly access the CoreCamera instance in Camera (but I'm not sure if it is recommended).

I recommend that you look at Camera sources for a better understanding, especially line 102 and the definition of on_play().

Halkiam
  • 51
  • 3
  • Hello! I have tried the `play` property of `Camera` but it still crashes. I have detected that it crashes on `self._buffer = frame.reshape(-1)` due to buffer overflow when the second camera object is initialized. The only thing I can do, is to merge those camera features together (Camera + Barcode camera), then no such issue will occur. – Hunter91151 Feb 16 '20 at 10:00
  • If you could give a Minimal, Reproducible Example, I could test it to see if I find something. – Halkiam Feb 16 '20 at 20:09
  • Hello! You can copy my code twice and change screen class name to other or you can create the two Camera screens and try to switch between them a few times and you will get this issue. Thanks. – Hunter91151 Feb 17 '20 at 11:14
  • I created two classes `CameraForm` and `BareCode` (in the `.py` and `.kv` files) with exactly the same code, I tried to switch between the `Screen` several times and I had no problem, everything works. I tested the code on Debian 10, I don't know if it can change anything. – Halkiam Feb 17 '20 at 20:30
  • I am developing it on Windows 10. On Android no such issue is present. I merged Camera features, then disabled/enabled the appropriate widgets and it works well. Thank you. – Hunter91151 Feb 17 '20 at 21:58
  • It says in the documentation that the camera initialization is asynchronous maybe the image is white because the camera hasn't initialized yet. – mhsquire83 Oct 20 '20 at 17:40