在 Kivy 布局上显示 OpenCV 图像结果和绘图
Posted
技术标签:
【中文标题】在 Kivy 布局上显示 OpenCV 图像结果和绘图【英文标题】:Displaying an OpenCV Imageresult and Plots on Kivy Layouts 【发布时间】:2021-12-03 20:17:52 【问题描述】:我是 OpenCV 的初学者,是一个试图创建 android 应用程序的 kivy。
我的应用应该显示通过一些 OpenCV 命令的图像。
目前我无法在我的 Kivy 布局中显示这些图像。
我知道您可以通过以下方式在 Kivy 上显示图像:
Image:
source: 'Images/Cats.jpg'
但是当我得到一个像这个阈值图像这样的“编辑”图像时,我需要另一种方法:
threshold, thresh_inverse = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV)
cv.imshow('Easy Threshold INV', thresh_inverse)
与我想在 Kivy 布局中显示的直方图相同。
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()
如果有人可以给我提示以在我的 Kivy 布局 id 上显示它们,非常感谢。
感谢您的帮助!
【问题讨论】:
文件.kv
仅加载一次 - 在开始时。稍后您必须使用 Python 代码更改 Kivy 中的image.source
。使用 plt.show()
对此毫无用处。它可能需要将绘图保存在文件中或io.BytesIo
中并在 Kivy 中加载。
嘿@furas 谢谢你的回答。更改 image.source 不是一个选项,因为我没有从 OpenCV 保存编辑后的图像。 OpenCV 应该从 image.source 中获取该图片并将其设置为阈值,然后显示它。明天我会看一段 YouTube 视频 (youtu.be/83C4tl8scoY),展示如何在 Kivy 的 Plot 中显示。那可能会有所帮助。给大家分享一下。
【参考方案1】:
文件.kv
仅在启动时加载,之后您必须使用Python代码更新image.source
或image.texture
。
cv
保持图像为numpy array
,所以我使用numpy
生成随机数组,转换为kivy Texture
并分配给现有的Image
。
我使用 Clock
每 0.25 秒重复一次,但您可以使用 Button
运行它。
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()
结果:
plt
可能需要不同的方法。它可能需要将绘图保存在io.BytesIO
(模拟内存中的文件)并将其从io.BytesIO
读取到CoreImage
并将CoreImage.texture
复制到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()
结果:
【讨论】:
我在第一个示例中添加了cv2.circle()
。以上是关于在 Kivy 布局上显示 OpenCV 图像结果和绘图的主要内容,如果未能解决你的问题,请参考以下文章