Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending kivy android video feed to imagezmq server #70

Open
ChesterProgram opened this issue Nov 12, 2021 · 8 comments
Open

Sending kivy android video feed to imagezmq server #70

ChesterProgram opened this issue Nov 12, 2021 · 8 comments

Comments

@ChesterProgram
Copy link

is it possible to send android video feed using kivy and opencv to the imagezmq server?

@jeffbass
Copy link
Owner

I don't know. I have never used kivy. Looking at its docs, it seems likely that it could work. I don't know if there are any incompatibilities with the combination of kivy, numpy, opencv and ZMQ. I suggest you give it a try with one of the imageZMQ test pairs. Please comment back here with what you find out.

Thanks,
Jeff

@ChesterProgram
Copy link
Author

So I have a question... does imagezmq only send opencv images or any images?

@jeffbass
Copy link
Owner

imagezmq sends opencv images or jpg images (or any image that is a "binary blob" that can be placed in a buffer). The send_image and recv_image methods are specific to opencv images. The send_jpg and recv_jpg were implemented to send binary buffers holding jpg images, but any arbitrary binary buffer can be sent using those methods. There are examples in the test folder and the examples folder. The imagezmq API is here.

@ChesterProgram
Copy link
Author

This is the Client Code

 from kivy.uix.camera import Camera
from kivy.app import App
from kivy.lang import Builder
from kivy.utils import platform
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from threading import Thread
from kivy.clock import Clock
import socket
import imagezmq
import cv2
import numpy as np

if platform == "android":
    from android.permissions import Permission, request_permissions

    request_permissions([Permission.READ_EXTERNAL_STORAGE,
                         Permission.WRITE_EXTERNAL_STORAGE,
                         Permission.INTERNET,
                         Permission.CAMERA])

Builder.load_string("""
<MyLayout>:
    AndroidCamera:
        index: 0
        id: a_cam
        resolution: (640, 480)
        play: True
        canvas.before:
            PushMatrix
            Rotate:
                angle: 0
                origin: self.center
            Scale:
                x: self.cam_ratio
                y: self.cam_ratio
                origin: self.center
        canvas.after:
            PopMatrix
""")

class AndroidCamera(Camera):
    camera_resolution = (640, 480)
    cam_ratio = camera_resolution[0] / camera_resolution[1]

class MyLayout(BoxLayout):
    pass



class MyApp(App):
    rpiName = socket.gethostname()
    sender = imagezmq.ImageSender(connect_to='tcp://192.168.0.124:5555')
    jpeg_quality = 95

    def build(self):
        return MyLayout()

    def send(self, jpg_image):
        self.sender.send_jpg(self.rpiName, jpg_image)

    def on_start(self):
        Clock.schedule_once(self.sending, 1)

    def sending(self, dt):
        cam = self.root.ids.a_cam
        image_object = cam.export_as_image(scale=round((400 / int(cam.height)), 2))
        w, h = image_object._texture.size
        frame = np.frombuffer(image_object._texture.pixels, 'uint8').reshape(h, w, 4)
        BGR = cv2.cvtColor(frame, cv2.COLOR_RGBA2BGR)
        ret_code, jpg_image = cv2.imencode(
            ".jpg", BGR, [int(cv2.IMWRITE_JPEG_QUALITY), self.jpeg_quality])
        Thread(target=self.send, args=(jpg_image, )).start()
        Clock.schedule_once(self.sending, 0.015)

if __name__ == "__main__":
    MyApp().run()

@ChesterProgram
Copy link
Author

This is the server code

from imutils import build_montages
import numpy as np
import imagezmq
import cv2

imageHub = imagezmq.ImageHub()

while True:
    rpiName, jpg_image = imageHub.recv_jpg()
    frame = cv2.imdecode(np.frombuffer(jpg_image, dtype='uint8'), -1)
    imageHub.send_reply(b'OK')
    cv2.imshow(rpiName, frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

cv2.destroyAllWindows()

@jeffbass
Copy link
Owner

Thanks for sharing your code! I'm sure others will find it helpful.

@Eliastoomme
Copy link

@jeffbass
Can you please share your buildozer.spec file?
I'm also trying to create an android app that sends frame with imagezmq to a server.
I've managed to get it working on PC, but not on Android as it when building.
I know its been long for this, but I will be really grateful if you help.

@jeffbass
Copy link
Owner

jeffbass commented Jul 4, 2023

I don't use Android. I will leave this for @ChesterProgram (who opened this issue & posted the above code) to reply to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants