【问题标题】:Cannot Process decoded Image files, Flask, OpenCV无法处理解码的图像文件、Flask、OpenCV
【发布时间】:2021-04-19 18:12:28
【问题描述】:

我通过客户端文件接收到flask 应用程序的一堆图像。

client.py

# Generate the parallel requests based on the ThreadPool Executor
from concurrent.futures import ThreadPoolExecutor as PoolExecutor
import sys
import time
import glob
import requests
import threading
import uuid
import base64
import  json
import os

#send http request
def call_object_detection_service(image):
    try:

        url = str(sys.argv[2])
        data = {}
        #generate uuid for image
        id = uuid.uuid5(uuid.NAMESPACE_OID, image)
        # Encode image into base64 string
        with open (image, 'rb') as image_file:
            data['image'] =  base64.b64encode(image_file.read()).decode('utf-8')

        data['id'] = str(id)
        headers = {'Content-Type': 'application/json'}

        response = requests.post(url, json= json.dumps(data), headers = headers)

        if response.ok:
            output = "Thread : {},  input image: {},  output:{}".format(threading.current_thread().getName(),
                                                                        image,  response.text)
            print(output)
        else:
            print ("Error, response status:{}".format(response))

    except Exception as e:
        print("Exception in webservice call: {}".format(e))

# gets list of all images path from the input folder
def get_images_to_be_processed(input_folder):
    images = []
    for image_file in glob.iglob(input_folder + "*.jpg"):
        images.append(image_file)
    return images

def main():
    ## provide argumetns-> input folder, url, number of wrokers
    if len(sys.argv) != 4:
        raise ValueError("Arguments list is wrong. Please use the following format: {} {} {} {}".
                         format("python iWebLens_client.py", "<input_folder>", "<URL>", "<number_of_workers>"))

    input_folder = os.path.join(sys.argv[1], "")
    images = get_images_to_be_processed(input_folder)
    num_images = len(images)
    num_workers = int(sys.argv[3])
    start_time = time.time()
    #craete a worker  thread  to  invoke the requests in parallel
    with PoolExecutor(max_workers=num_workers) as executor:
        for _ in executor.map(call_object_detection_service,  images):
            pass
    #elapsed_time =  time.time() - start_time
    #print("Total time spent: {} average response time: {}".format(elapsed_time, elapsed_time/num_images))


if __name__ == "__main__":
    main()

我像这样解码它们 烧瓶应用

app = Flask(__name__)

c = 1
@app.route('/api/object_detection', methods = ['POST'])
def main():
    global c
    try:
        data = request.get_json(force=True)
        uid = data.get('id')
        image = data.get('image')
        print(image)
        im = base64.decodebytes(image)
        with open("image{}".format(c), 'wb') as f:
            f.write(im)
        c += 1
        for l in range(128):
            img = cv2.imread("image{}".format(l), cv2.IMREAD_ANYCOLOR);
            # load the neural net.  Should be local to this method as its multi-threaded endpoint
            nets = load_model(CFG, Weights)
            s = do_prediction(img, nets, Lables)
            return jsonify(s)

    except Exception as e:
        print(e)




if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True, threaded=True)

这会创建不同大小的图像文件,但我无法在图像查看器中查看它们。收到的文件是jpg 文件。忽略这一点,我继续处理,我得到了

TypeError: The view function for 'main' did not return a valid response. The function either returned None or ended without a return statement.
Incorrect padding
Incorrect padding
[INFO] loading YOLO from disk...
'NoneType' object has no attribute 'shape'

图片是这样发送的。

python iWebLens_client.py inputfolder/ http://192.168.29.75:5000/api/object_detection 4

图像是这样接收的。

b'"{\\"image\\": \\"/9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA......fiU05tQopHNf//Z\\", \\"id\\": \\"e3ad9809-b84c-57f1-bd03-a54e25c59bcc\\"}"'

我想我需要decode('utf-8') 这个,但不知道怎么做。

【问题讨论】:

  • image = request.data -- 但是您的客户端正在发送 JSON 字符串,而不仅仅是图像...
  • request.data 是“字符串”前面的原始数据(注意b)。您可能不想自己管理原始数据。值得庆幸的是,flask 可以为您处理这个问题。有关如何从request 获取格式化数据的详细信息,请参阅this 答案。您可能可以通过request['image'] 获取图像数据。然后你需要根据它的编码方式对其进行解码。
  • @noslenkwah 没有办法请求['image']。客户端发送json,变成字符串,即使我得到图像值,编码然后解码,它仍然不起作用。只是在should be bytes not str 错误消息之间跳转。

标签: python json api opencv flask


【解决方案1】:

目前,您在客户端对数据进行双重编码。在请求中,传递的参数已经转换为 JSON。

只需将 dict 作为 json 参数传递。

def call_object_detection_service(image):
    try:

        url = str(sys.argv[2])
        data = {}
        #generate uuid for image
        id = uuid.uuid5(uuid.NAMESPACE_OID, image)
        # Encode image into base64 string
        with open (image, 'rb') as image_file:
            data['image'] =  base64.b64encode(image_file.read()).decode('utf-8')

        data['id'] = str(id)
        headers = {'Content-Type': 'application/json'}

        # HERE IS THE CHANGE !!!
        response = requests.post(url, json=data, headers=headers)

        if response.ok:
            output = "Thread : {},  input image: {},  output:{}".format(
                threading.current_thread().getName(),
                image, 
                response.text
            )
            print(output)
        else:
            print ("Error, response status:{}".format(response))

    except Exception as e:
        print("Exception in webservice call: {}".format(e))

现在可以在服务器上以 JSON 格式接收数据并提取到字典中。

@app.route('/api/object_detection', methods=['POST'])
def main():
    data = request.get_json(force=True)
    uid = data.get('id')
    image = data.get('image')
    # ... decode the base64 data here ...
    return jsonify(message='done')

【讨论】:

  • 我确实试过这个。 'str' object has no attribute 'get'json 是一个字符串,它需要bytes。您无法访问这样的值。我必须将传入的json 添加到list,然后我才能访问image 值。即使这样也不会被解码,因为它又是一个字符串。
  • @AbhishekRai 因为您将客户端的 dict 转换为 JSON 字符串,该字符串再次转换为 JSON。
  • @AbhishekRai 这就是我的工作方式。我希望并认为它也应该对您有用,否则请给我留言。
  • 问题不是获取图像字符串,而是解码它。每次需要字节时它都是一个字符串,这就是问题所在,让我用你在问题中的实现来更新代码。错误又是expected bytes-like object, not str
  • 如果我对字符串进行编码然后对其进行解码,则会出现错误,但随后出现问题中的原始错误'NoneType' object has no attribute 'shape',图像文件已创建,它们有大小,但被视为@ 987654331@ 类型对象。哦! padding 错误也消失了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
相关资源
最近更新 更多