Home > Back-end >  Displaying an OpenCV Imageresult and Plots on Kivy Layouts
Displaying an OpenCV Imageresult and Plots on Kivy Layouts

Time:10-16

im an beginner with OpenCV an kivy trying to create an Android application.

My App should display images which went through some OpenCV Commands.

At the moment im having trouble to show these Images im my Kivy Layouts.

I know that you can display Images on Kivy with:

    Image:

                source: 'Images/Cats.jpg'

But i need an other way when i got an "edited" Image like this Threshold Image:

threshold, thresh_inverse = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV)
cv.imshow('Easy Threshold INV', thresh_inverse)

Same with the plot of an Histogram which I want to display in my Kivy Layout.

img = cv.imread('C:\\Users\\julia\\Desktop\\Images_HHN\\Cats3.jpg')
cv.imshow('Bsp. HHN', img)
blank = np.zeros(img.shape[:2],dtype='uint8')
Circle = cv.circle(blank, (img.shape[1] // 2, img.shape[0] // 2), 100, 255, -1)
cv.imshow('Circle', Circle)
mask= cv.bitwise_and(img,img, mask= Circle )
cv.imshow('MaskPic', mask)

plt.xlim([0, 256])
plt.show()
colors = ('b', 'g', 'r')
plt.figure()
plt.title('Color Histogramm')
plt.xlabel('Bins')
plt.ylabel('n pixels')


for i, col in enumerate(colors):
    hist = cv.calcHist([img], [i], None, [256], [0,256 ])
    plt.plot(hist,color=col)
    plt.xlim([0,256])


plt.show()

If someone could give me tips to Display them on my Kivy Layout id be very thankfull.

Thank you for your help!

CodePudding user response:

File .kv is loaded only at start and later you have to use Python code to update image.source or image.texture.

cv keeps image as numpy array so I used numpy to generate random array, convert to kivy Texture and assign to existing Image.

I used Clock to repeate it every 0.25 s but you can use Button to run it.

from kivy.app import App
from kivy.uix.image import Image
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import numpy as np
import cv2

# --- functions ---

def generate_texture():
    """Generate random numpy array `500x500` as iamge, use cv2 to change image, and convert to Texture."""
    
    # numpy array
    img = np.random.randint(0, 256, size=(500, 500, 3), dtype=np.uint8)

    cv2.circle(img, (img.shape[1]//2, img.shape[0]//2), 100, 255, -1)

    data = img.tobytes()

    # texture
    texture = Texture.create(size=(500, 500), colorfmt="rgb")
    texture.blit_buffer(data, bufferfmt="ubyte", colorfmt="rgb")
    
    return texture

def update_image(dt):
    """Replace texture in existing image."""
    
    image.texture = generate_texture()

# --- main ---
 
# empty image at start    
image = Image()
    
class MyPaintApp(App):
    def build(self):
        return image

# run function every 0.25 s
Clock.schedule_interval(update_image, 0.25)

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

Result:

enter image description here


plt may need different method. It may need to save plot in io.BytesIO (which simulates file in memory) and read it from io.BytesIO to CoreImage and copy CoreImage.texture to Image.texture.

from kivy.app import App
from kivy.uix.image import Image, CoreImage
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import io
import numpy as np
import matplotlib.pyplot as plt

# --- functions ---

def generate_texture():
    """Generate random numpy array, plot it, save it, and convert to Texture."""
    
    # numpy array
    arr = np.random.randint(0, 100, size=10, dtype=np.uint8)
    
    # plot
    plt.clf() # remove previous plot
    plt.plot(arr)
    
    # save in memory
    data = io.BytesIO()
    plt.savefig(data)
    
    data.seek(0)  # move to the beginning of file
    
    return CoreImage(data, ext='png').texture
    
def update_image(dt):
    """Replace texture in existing image."""
    
    image.texture = generate_texture()
    
# --- main ---
 
# empty image at start    
image = Image()
    
class MyPaintApp(App):
    def build(self):
        return image

# run function every 0.25 s
Clock.schedule_interval(update_image, 0.25)

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

Result:

enter image description here

  • Related