安卓手机可以利用pydroid3程序跑opencv3,现在测试HSV采集。

程序显示黑屏的主要原因是颜色格式不匹配。OpenCV 默认使用 BGR 格式,而 Kivy 期待的是 RGB 格式。此外,您需要在创建纹理时设置 allow_stretch 属性,并在显示图像时正确更新纹理。

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.label import Label
from kivy.uix.slider import Slider
import cv2

class SliderWithLabel(BoxLayout):
    def __init__(self, label_text, parent, var_name, min_val, max_val, **kwargs):
        super().__init__(**kwargs)
        self.orientation = 'horizontal'
        self.spacing = 10  # 增加间距
        self.size_hint = (1, None)
        self.height = 50  # 设置固定高度

        self.label = Label(text=label_text, size_hint=(0.3, 1))
        self.add_widget(self.label)

        self.slider = Slider(min=min_val, max=max_val, value=getattr(parent, var_name), size_hint=(0.7, 1))
        self.slider.bind(value=lambda instance, value: setattr(parent, var_name, int(value)))
        self.add_widget(self.slider)

class HSVAdjuster(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = 'vertical'
        self.spacing = 10  # 增加整体布局的间距

        # 初始化摄像头
        self.capture = cv2.VideoCapture(0)
        if not self.capture.isOpened():
            print("Error: Could not open camera.")
            return

        # 设置摄像头分辨率
        self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1000)
        self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1000)

        # 创建显示区域
        self.image_widget = Image()
        self.add_widget(self.image_widget)

        # 添加控制面板
        control_panel = BoxLayout(orientation='vertical', size_hint=(1, None), height=300, spacing=10)
        self.add_widget(control_panel)

        # HSV 滑块
        self.h_min = 0
        self.h_max = 180
        self.s_min = 0
        self.s_max = 255
        self.v_min = 0
        self.v_max = 255

        # 创建滑块并添加到控制面板
        control_panel.add_widget(SliderWithLabel('H Min', self, 'h_min', 0, 180))
        control_panel.add_widget(SliderWithLabel('H Max', self, 'h_max', 0, 180))
        control_panel.add_widget(SliderWithLabel('S Min', self, 's_min', 0, 255))
        control_panel.add_widget(SliderWithLabel('S Max', self, 's_max', 0, 255))
        control_panel.add_widget(SliderWithLabel('V Min', self, 'v_min', 0, 255))
        control_panel.add_widget(SliderWithLabel('V Max', self, 'v_max', 0, 255))

        # 初始化纹理
        self.texture = None

        # 计时器
        Clock.schedule_interval(self.update_frame, 1.0 / 30.0)

    def update_frame(self, dt):
        if not self.capture.isOpened():
            return

        ret, frame = self.capture.read()
        if not ret:
            print("Error: Could not read frame.")
            return

        # 转换颜色空间到HSV
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        # 创建掩码
        lower = (self.h_min, self.s_min, self.v_min)
        upper = (self.h_max, self.s_max, self.v_max)
        mask = cv2.inRange(hsv, lower, upper)

        # 应用掩码到原始帧
        res = cv2.bitwise_and(frame, frame, mask=mask)

        # 将结果从BGR转换为RGB
        res = cv2.cvtColor(res, cv2.COLOR_BGR2RGB)

        # 将帧转换为纹理
        buf = res.tostring()
        if self.texture is None:
            self.texture = Texture.create(size=(res.shape[1], res.shape[0]), colorfmt='rgb')
            self.texture.flip_vertical()
        self.texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
        self.image_widget.texture = self.texture

    def on_stop(self):
        if self.capture.isOpened():
            self.capture.release()

class HSVAdjusterApp(App):
    def build(self):
        return HSVAdjuster()

    def on_stop(self):
        self.root.on_stop()

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

发表评论