我正在尝试创建一个图像上的标记,允许用户选择颜色,标记特征等。最终我想有相应的图像像素,以进一步通过opencv使用。在
我有很多麻烦得到预期的颜色下触摸,它有时会返回像洋红这样的颜色,甚至在示例图像中都没有。在
我很确定问题出在如何将触摸位置转换为我要传递给read_pixel函数的值。在
我尝试过许多不同的解决方案,但都没有成功,所以我觉得我在这里缺少了一些东西。在
在主.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()
在点选择器.kv在
^{pr2}$这是我用来测试“彩虹”的图像_棋盘.jpg““
我相信这是吉普车本身的一个缺陷。特别是我认为line 901 at the kivy/core/image/__init__.py
是错误的。应该是的
^{pr2}$相反。在
这里重要的是,出于性能原因,内存中的位图图像在4字节地址上对齐。因此有一个显式的
data.rowlength
字段。通常这一行工作得很好,因为图像通常是对齐的,这样data.rowlength = data.width * size
。但是您的特定图像是不同的:它使用3字节RGB
格式(没有alpha),它的宽度是奇数561
,即data.width * size
=1683
,因此data.rowlength
应该向上取整为1684
,实际上是这样,但是代码没有考虑到这一点。这意味着你经常从两个连续的像素和随机旋转的RGB组件读取颜色。在另外,由于您的图像使用JPEG格式,所以“单元格”之间的边界并不严格。若您非常努力地放大,您可以从左下角看到一些压缩伪影。在
那些被前面提到的随机颜色分量旋转错误所掩盖的伪影给了你非常奇怪(似乎不存在)的颜色。在
可能的解决办法
kivy/core/image/__init__.py
文件(我试过了,它似乎工作得很好)。在相关问题 更多 >
编程相关推荐