有没有办法在Kivy小部件或窗口中使用OpenCV setMouseCallBack?

6rvt4ljy  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(152)

我在一个使用Python和Kivy的项目中工作。有一个预先存在的软件,用于识别图像中的模式,有一个完全工作的版本,但它只使用命令行。现在它需要一个图形用户界面,选择的库是Kivy。我面临的主要困难是,软件的核心使用OpenCV,并与Kivy集成是非常令人沮丧的。简而言之,它是这样工作的:1-显示OpenCV窗口,用户必须在其中选择感兴趣区(ROI)。2-选择后,调用另一个函数(主函数),并在先前设置的区域内开始分析。3-分析完成后,结果以图像和报告的形式显示。
我的问题是:我无法将此openCV窗口带到Kivy界面。到目前为止,我设法完成的是在GUI中镜像此OpenCV图像,但ROI选择仍必须从OpenCV窗口中完成,因此这不是我所需要的。是否有方法在Kivy窗口中"转换" OpenCV窗口?如果没有,您有什么建议?
先谢谢你了
我已经试过了:

  • 将OpenCV窗口镜像到Kivy GUI(部分工作,因为鼠标输入不工作)

期望值:

  • 将图像中的输入作为主函数内部使用的值。
7xzttuei

7xzttuei1#

我试图将我的代码作为注解包含在您的答案中,但是没有足够的空间。下面是我找到的代码的一个可复制的示例,它部分地回答了我的问题。

from kivy.app import App
from kivy.uix.image import Image
from kivy.properties import ListProperty
from kivy.lang import Builder

Builder.load_string('''
<ROIImage>
    canvas:
        Color:
            rgba: root.roi_color
        Rectangle:         
            pos: root.start_pos
            size: root.current_pos[0] - root.start_pos[0], \
              root.current_pos[1] - root.start_pos[1]

''')

class ROIImage(Image):
 start_pos = ListProperty([0, 0])
 current_pos = ListProperty([0, 0])
 roi_color = ListProperty([1, 1, 1, 0.5])

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        touch.grab(self)
        self.current_pos = self.start_pos = touch.pos
        return True
    return False

def on_touch_move(self, touch):
    if touch.grab_current is self:
        self.current_pos = touch.pos
        print(f'current pos: {touch.pos}')
        if (self.start_pos[0] < self.current_pos[0]) and (self.start_pos[1] 
< self.current_pos[1]):
            print("Top Right")
            self.roi_color = (100 / 255, 143 / 255, 165 / 255, 0.6)

        elif (self.start_pos[0] < self.current_pos[0]) and 
(self.start_pos[1] > self.current_pos[1]):
            print("Bottom Right")
            self.roi_color = (23 / 255, 143 / 255, 54 / 255, 0.6)

        elif (self.start_pos[0] > self.current_pos[0]) and 
(self.start_pos[1] < self.current_pos[1]):
            print("Top Left")
            self.roi_color = (100 / 255, 93 / 255, 65 / 255, 0.6)

        elif (self.start_pos[0] > self.current_pos[0]) and 
(self.start_pos[1] > self.current_pos[1]):
            print("Bottom Left")
            self.roi_color = (100 / 255, 45 / 255, 34 / 255, 0.6)
        return True
    return False

def on_touch_up(self, touch):
    if touch.grab_current is self:
        self.current_pos = touch.pos
        print(f'End pos: {touch.pos}')
        return True
    return False

def clear(self):
    self.roi_color = (1, 1, 1, 0)

if __name__ == '__main__':
    kv_test = '''
BoxLayout:
    orientation: 'vertical'
    ROIImage:
        id: roi_image
        source: 'image.jpg'
   Button:
        size_hint_y: None
        height: dp(48)
        text: 'Clear'
        on_release: 
            roi_image.clear()
'''

class ROIIMAGEApp(App):

    def build(self):
        return Builder.load_string(kv_test)

ROIIMAGEApp().run()

我之所以说部分是因为它需要保存在本地内存中的图像才能工作,我无法将相机本身作为输入来使它工作(抱歉,我是Python新手,对Kivy更是新手)。
无论如何,到目前为止非常感谢你!最好的问候

相关问题