Dash应用程序不显示使用opencv修改的图像

1cklez4t  于 2023-03-03  发布在  其他
关注(0)|答案(1)|浏览(138)

Dash应用程序应该允许用户从浏览器上传图像,然后使用opencv进行一些操作,然后需要显示修改后的图像。我的问题是update_output函数。当我传递i时,我在浏览器中看到图像,但是如果我传递dataURI(使用opencv的图像修改版本),那么图像永远不会在浏览器中显示。有人能帮助我吗?

#app = Dash(__name__, external_stylesheets=external_stylesheets)
  app.layout = html.Div([
      dcc.Upload(
          id='upload-image',
          children=html.Div([
              'Drag and Drop or ',
              html.A('Select Files')
          ]),
      ),
      html.Div(id='output-image-upload'),
      dcc.Store(id='store-data', storage_type='memory')
  ])
  
  @app.callback(Output('store-data', 'data'), Input('upload-image', 'contents') )
  
  def store_data(value): return value
  
  def data_uri_to_cv2_img(uri):
      encoded_data = uri.split(',')[1]
      nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
      img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
      return img
  
  def parse_contents(contents):
      return html.Div([
          html.Img(src=contents, style={'height':'10%', 'width':'10%'})
      ])
  
  @app.callback(
      Output('output-image-upload', 'children'),
      Input('store-data', 'data')
  )
  
  def update_output(images):
      if not images:
          return
  
      children = []
      for i in images:
        img1 = data_uri_to_cv2_img(i)
        #some operations -- skip for now
        _, buffer = cv2.imencode('.jpg', img1)
        jpg_as_text = base64.b64encode(buffer.tobytes())
        dataURI = 'data:image/jpeg;base64,' + str(jpg_as_text) 
  
      children.append(parse_contents(dataURI))
      return children
  
  
  if __name__ == '__main__':
     app.run_server(host='localhost',port=8005, debug = True)
2wnc66cl

2wnc66cl1#

您遇到的问题是回调update_output()当前期望images的列表,而其输入实际上是一个 * 单个 * 图像:当store_data()回调函数获取上传映像的内容时,它会将该内容直接放入存储区,并 * 覆盖 * 先前存在的任何数据。
如果目标是附加这些图像,则需要使用结构化为列表的数据初始化存储,并修复第一个回调:

app.layout = html.Div([
    # ...
    dcc.Store(id='store-data', storage_type='memory', data=[])
])

# ...

@app.callback(
    Output('store-data', 'data'),
    Input('upload-image', 'contents'),
    State('store-data', 'data'))        # <- use State() to get current data
def store_data(value, data):
    if value is not None:
        data.append(value)
    return data

此外,不确定这是否是复制/粘贴代码的结果,但似乎在第二个回调中存在缩进问题。
另一件事是base64.b64encode()returns a binary string (ie. bytes),所以你仍然需要将这些字节转换回ascii(否则最终的dataURI将包含二进制序列b'<data>',就像data:image/jpeg;base64,b'<data>'一样):

@app.callback(
    Output('output-image-upload', 'children'),
    Input('store-data', 'data')
)
def update_output(images):
    if not images:
        return

    children = []
    for i in images:
        img1 = data_uri_to_cv2_img(i)
        #some operations -- skip for now
        _, buffer = cv2.imencode('.jpg', img1)
        jpg_as_text = base64.b64encode(buffer.tobytes())
        dataURI = 'data:image/jpeg;base64,' + str(jpg_as_text, 'ascii')  # <- 

    children.append(parse_contents(dataURI))
    return children

相关问题