[英]How to return coordinates of an interactively drawn rectangle in google colab with plotly
我是新来的。 我想在图像上以交互方式绘制一些边界框并将它们的坐标获取到列表中(左上角,右下角)。 这应该在 google colab 中完成,所以 CV2 不起作用。 此链接提供了一个交互式选择(拖动和绘制)图像区域的示例,而此链接可用于使用 plotly 提取绘图上的坐标。 我仍然无法弄清楚如何将这两个示例组合在一起并返回边界框坐标。 我在下面添加了这些代码片段。
要在图像上绘制边界框:-
!wget https://gamingnewsanalyst.com/wp-content/uploads/2020/03/Crysis-3-Free-Download-800x450.jpg
import plotly.express as px
import cv2
img = cv2.cvtColor(cv2.imread('/content/Crysis-3-Free-Download-800x450.jpg'),cv2.COLOR_BGR2RGB)
fig = px.imshow(img)
fig.update_layout(
dragmode='drawrect',
newshape=dict(line_color='cyan'))
fig.show()
获取鼠标点击点的坐标:-
import plotly.graph_objects as go
from google.colab import output
output.enable_custom_widget_manager()
import numpy as np
np.random.seed(1)
x = np.random.rand(100)
y = np.random.rand(100)
f = go.FigureWidget([go.Scatter(x=x, y=y, mode='markers')])
scatter = f.data[0]
colors = ['#a3a7e4'] * 100
scatter.marker.color = colors
scatter.marker.size = [10] * 100
f.layout.hovermode = 'closest'
# create our callback function
def update_point(trace, points, selector):
c = list(scatter.marker.color)
s = list(scatter.marker.size)
for i in points.point_inds:
c[i] = '#bae2be'
s[i] = 20
print(points)
with f.batch_update():
scatter.marker.color = c
scatter.marker.size = s
scatter.on_click(update_point)
f
当我单击一个点时,此代码将在输出下方给出
Points(point_inds=[6],
xs=[0.1862602113776709],
ys=[0.015821242846556283],
trace_name='trace 0',
trace_index=0)
我的预期输出应该是绘制的边界框的坐标。
[[100,100],[500,400]] ## [[x0,y0],[x1,y1]]
[[200,130],[400,300]]
任何帮助深表感谢。 提前致谢。
经过一番搜索,找到了这个例子,它告诉了如何做到这一点。 我对其进行了修改并部分插入到一个类中,如下所示以满足我的全部要求。
import plotly.express as px
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from jupyter_dash import JupyterDash
import cv2
import numpy as np
coords = []
depths = []
app = JupyterDash(__name__)
@app.callback(
Output("bbox-data", "children"),
Input("middle-sai", "relayoutData"),
prevent_initial_call=True,
)
def on_new_annotation(relayout_data):
global coords,depths
if "shapes" in relayout_data:
x0 = int(relayout_data["shapes"][-1]['x0'])
y0 = int(relayout_data["shapes"][-1]['y0'])
x1 = int(relayout_data["shapes"][-1]['x1'])
y1 = int(relayout_data["shapes"][-1]['y1'])
coords_dict = {'x0':x0,'y0':y0,'x1':x1,'y1':y1}
coords.append([[y0,x0],[y1,x1]])
depths.append(None)
return html.Div([html.Div(str(coords_dict)),html.Div(dcc.RadioItems(['shallow', 'deep'],inline=True,id = "depth-sel"))],style={"color": "white"})
else:
return dash.no_update
@app.callback(
Output('all-bboxes','children'),
Input("depth-sel","value"),
)
def display_final_list(depth_val):
global coords,depths
if (depth_val == 'deep'):
depths[-1] = 1
elif (depth_val == 'shallow'):
depths[-1] = 0
flist = ''
for i in range(len(coords)):
flist += str(coords[i])
if (depths[i]==1):
flist += " deep "
elif (depths[i]== 0):
flist += " shallow "
else:
flist += " " + str(depths[i]) + " "
return flist
class test_show():
def __init__(self):
global coords,depths
coords = []
depths = []
self.img = cv2.cvtColor(cv2.imread('/content/Crysis-3-Free-Download-800x450.jpg'),cv2.COLOR_BGR2RGB)
fig = px.imshow(self.img)
fig.update_layout(
autosize=False,
# width=500,
height=400,
dragmode='drawrect',
newshape=dict(line_color='cyan'))
app.layout = html.Div(
[
dcc.Graph(id="middle-sai", figure=fig),
html.Pre(id="bbox-data",style={"color": "white"}),
html.Div(id='all-bboxes',style={"color": "white"}),
]
)
def show_image(self):
app.run_server(debug=False,mode='inline')
t = test_show()
t.show_image()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.