0

I'm trying to make apk file from using python. This code is using cv2.VideoCapture(0) to make phone camera application. Here's my code

# Import kivy dependencies first
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

# Import kivy UX components
from kivy.uix.image import Image

# Import other kivy stuff
from kivy.clock import Clock
from kivy.graphics.texture import Texture

# Import other dependencies
import cv2

class CamApp(App):
    def build(self):
        self.vid = cv2.VideoCapture(0)
        self.web_cam = Image()
        layout = BoxLayout()
        layout.add_widget(self.web_cam)
        #self.capture = cv2.VideoCapture(0)
        Clock.schedule_interval(self.update, 1.0 / 33.0)

        self.vid.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        self.vid.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

        #w = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
        #h = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
        #print("너비 {} 높이 {}".format(w, h))

        return layout

    def update(self, *args):
        ret, frame = self.vid.read()

        #frame = cv2.flip(frame, 0)

        # Flip horizontal and convert image to texture
        buf = cv2.flip(frame, 0).tostring()

        img_texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
        img_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
        self.web_cam.texture = img_texture

if __name__ == '__main__':
    CamApp().run()

It works fine on PC and I used buildozer to make application. Here's my part of my buildozer.spec

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy,opencv

Anyway, when I played the application I made, it shuts off after kivy loading page. So I used adb and got an error message

AttributeError: 'NoneType' object has no attribute 'tostring'

I can't understand why this error messaged showed up because it worked well in my PC. Please help me...

Thank you!!

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
ywseo97
  • 51
  • 3
  • We need a traceback, any of your variables could be `None`. – Peter May 11 '22 at 09:47
  • Can I get more information? I'm not sure how to fix the code. And more, it works well in PC so it is still confusing to me. Thank you! – ywseo97 May 11 '22 at 10:06
  • Nvm, from the context I see that `cv2.flip(frame, 0)` is returning `None` for whatever reason. As to why I'm not sure, but it's a start point for you to debug, for example maybe the `frame` is empty or something? – Peter May 11 '22 at 10:21
  • Do you mean ```#frame = cv2.flip(frame, 0)``` this code? I am so sorry. In the original code ```#frame = cv2.flip(frame,0)``` was not existed. I edited my code, thank you. ```#frame = cv2.flip(frame, 0)```, this was my testing line because when I got the error at first, I thought ```ret``` or ```frame``` was the problem. So I just added that line. – ywseo97 May 11 '22 at 10:29
  • It says `None` has no attribute `tostring`, so I was meaning the `buf = cv2.flip(frame, 0).tostring()` line. It means that `flip` is returning None, so it fails on calling `.tostring()`. It might be worth checking if it's None and just returning early if so. – Peter May 11 '22 at 10:32
  • you must check for errors when using VideoCapture. `if not ret: return` – Christoph Rackwitz May 11 '22 at 10:40
  • @Peter , thanks for your reply. I am trying to understand what I have to make a change about ```buf = cv2.flip(frame, 0).tostring()```. But still it's hard to understand why it worked in PC... – ywseo97 May 11 '22 at 10:51
  • @Christoph Rackwitz, what do you exactly mean? Is it the same way as Peter said? – ywseo97 May 11 '22 at 10:53
  • I mean something like `if cv2.flip(frame, 0) is None: return`, though Christoph's reply looks like it'd be a lot better. – Peter May 11 '22 at 10:57
  • `assert self.vid.isOpened()` – Christoph Rackwitz May 11 '22 at 11:46
  • @ChristophRackwitz, can I get the location where I have to put ```assert self.vid.isOpened()```? and can I use use ```if``` instead of ```assert```? And is it correct that I use ```assert self.vid.isOpened()``` just below ```ret,frame = self.vid.read()```? After that I only get white screen in my phone. (I changed buildozer.spec ```requirements = python3,kivy,opencv,numpy ```) – ywseo97 May 11 '22 at 12:51
  • The main problem is the cv2.VideoCapture(0) cannot reach the android camera. So when you are trying to read frame, it returns nothing. The best thing to do is use kivy.uix.camera to get it work. You can find my solution here: https://stackoverflow.com/questions/61122285/ – Norbert Tiborcz Dec 01 '22 at 04:21

1 Answers1

0

try to do this:

def update(self, *args):
    ret, self.frame = self.vid.read()

    #frame = cv2.flip(frame, 0)

    # Flip horizontal and convert image to texture
    buf = cv2.flip(self.frame, 0).tobytes()

    img_texture = Texture.create(size=(self.frame.shape[1], self.frame.shape[0]), colorfmt='bgr')
    img_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
    self.web_cam.texture = img_texture
Azhar Khan
  • 3,829
  • 11
  • 26
  • 32
so-me
  • 23
  • 7