Ich versuche, Markierungen auf einem Bild zu erstellen, die es einem Benutzer erlauben, Farben auszuwählen, Features zu markieren usw. Letztendlich würde ich gerne das entsprechende Bildpixel für die weitere Verwendung über opencv haben.Warum gibt kivy read_pixel die erwartete Farbe nicht zurück?
Ich habe viel Mühe, die erwartete Farbe unter der Berührung zu bekommen, und es gibt manchmal Farben wie Magenta zurück, die nicht einmal im Beispielbild sind.
Ich bin mir ziemlich sicher, dass das Problem darin besteht, wie ich die Berührungsposition in die Werte umwandele, die ich an die read_pixel-Funktion übergebe.
Ich habe viele verschiedene Lösungen ohne Erfolg ausprobiert, also denke ich, dass ich etwas vermisse.
main.py
from kivy.app import App
from kivy.properties import ListProperty, ObjectProperty
from kivy.uix.image import AsyncImage
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
class Marker(Widget):
selected_color = ListProperty([0,1,0])
def __init__(self, **kwargs):
super(Marker, self).__init__(**kwargs)
self.selected_pos = None
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print("Touched at Marker: {0}".format(touch.spos))
def on_touch_move(self, touch):
self.set_position_from_touch(touch.spos)
def set_position_from_touch(self, spos):
# print("touch: {0}".format(touch))
self.image = self.parent.parent.image
x = spos[0] * self.image.width
y = spos[1] * self.image.height
# setting position of the widget relative to touch
self.pos = (x-self.width/2, y-self.height*(2/3))
# self.pos = (x, y)
print("widget position : {0}".format(self.pos))
# converting widget position to pixel(row, column of
selected_pixel = self.image.to_row_col(self.pos)
print("selected Pixel: {0}".format(selected_pixel))
try:
self.selected_color = self.image._coreimage.read_pixel(
selected_pixel[0],
selected_pixel[1])
# this skips conversion and just uses pos
# self.pos[0],
# self.pos[1])
except IndexError:
print("position out of range")
class MarkerManager(RelativeLayout):
def __init__(self, **kwargs):
super(MarkerManager, self).__init__(**kwargs)
self.marker_mode = None
self.features = []
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
child_touched = False
print("Touched: {0}".format(touch))
if self.children:
for child in self.children[:]:
if child.collide_point(touch.pos[0], touch.pos[1]):
child_touched = True
child.dispatch('on_touch_down', touch)
if not child_touched:
print("Touched only Image at: {0}".format(touch.spos))
marker = Marker()
self.features.append(marker)
self.add_widget(marker)
marker.set_position_from_touch(touch.spos)
class SelectedImage(AsyncImage):
def __init__(self, **kwargs):
super(SelectedImage, self).__init__(**kwargs)
self.allow_stretch=True
self.keep_ratio=False
def to_row_col(self, pos):
pixels_x = self._coreimage.width
pixels_y = self._coreimage.height
pixel_x = (pos[0]/self.width) * pixels_x
# pixel_y = (pos[1]/self.height) * self.pixels_y
pixel_y = (1 - (pos[1]/self.height)) * pixels_y
# should correspond to row column of image
return [int(pixel_x), int(pixel_y)]
class ImageScreen(Screen):
image = ObjectProperty()
manager = ObjectProperty()
def __init__(self, **kwargs):
super(ImageScreen, self).__init__(**kwargs)
class PointsSelectorApp(App):
def build(self):
return ImageScreen()
if __name__ == "__main__":
PointsSelectorApp().run()
pointsselector.kv
<ImageScreen>:
image: image_id
manager: manager_id
SelectedImage:
id: image_id
source: "rainbow_checkerboard.jpg"
keep_data: True
MarkerManager:
id: manager_id
<Marker>:
size_hint: None, None
size: "40dp", "40dp"
canvas:
Color:
rgb: self.selected_color
Ellipse:
pos: self.pos[0]+self.width/4, self.pos[1]+self.height/3
# pos: self.pos[0], self.pos[1]
size: self.width*.6, self.height*.6
hier ist mein Bild habe ich mit "rainbow_checkerboard.jpg"
Funktioniert Ihre Funktion 'to_row_col' korrekt? Hast du es manuell überprüft? Vergiss nicht, dass dein Bild wahrscheinlich so gestreckt ist, dass es die gleiche Größe wie das Widget hat, in dem es gespeichert ist. Betrachte 'allow_stretch: False', um dir beim Debuggen zu helfen. –
Ich erlaube Stretch, das Bild nimmt den ganzen Bildschirm ein und du kannst nicht vom Bild abklicken. Ich denke, dass die Methode to_row_col funktioniert. Das bedeutet, dass es die Position in Bezug auf die Widgetgröße normalisiert und dann mit den Dimensionen des Rohbilds multipliziert. Ob das genau das ist, was ich tun soll, ist eine andere Frage ... – mkrinblk
Wenn du noch Hilfe brauchst, werde ich es mir morgen ansehen. –