简体   繁体   English

类型错误:返回类型必须是字符串、字典、元组、响应实例或可调用的 WSGI,但它是一个列表

[英]Type Error: The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a list

I'm making a Flask App that would take an image input,process it and save the results in a JSON file,but after processing the image it gives me a Type Error mentioned in the title.To add more,it prints only one line and then stops;我正在制作一个 Flask 应用程序,它将输入图像,对其进行处理并将结果保存在 JSON 文件中,但是在处理图像后它会给我一个标题中提到的类型错误。要添加更多,它只打印一行然后停下来; Below is my Flask API that I'm using;下面是我正在使用的 Flask API;

    @app.route('/upload',methods=['GET','POST'])
def upload_analyze():

    if request.method == 'POST':
        # check if a file was passed into the POST request
        if 'file' not in request.files:
            flash('No file was uploaded.')
            return redirect(request.url)     
        f = request.files['file']
        filename = secure_filename(f.filename)
        f.save(filename)
        image = cv2.imread(filename)
        #f.save(secure_filename(f.filename))    

        #return 'file uploaded successfully'
        # image_file = request.files['image']


        clt = KMeans(n_clusters = 3)
        dataset = pd.read_csv('bb22.csv') 
        X = dataset.iloc[:, 1: 8].values
        sc = StandardScaler()
        global orig , r
            # load the image, convert it to grayscale, and blur it slightly
        #images = np.array(Image.open(image_file))
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        gray = cv2.GaussianBlur(gray, (7, 7), 0)

            # perform edge detection, then perform a dilation + erosion to
            # close gaps in between object edges
        edged = cv2.Canny(gray, 50, 100)
        edged = cv2.dilate(edged, None, iterations=1)
        edged = cv2.erode(edged, None, iterations=1)

            # find contours in the edge map
        cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if imutils.is_cv2() else cnts[1]

            # sort the contours from left-to-right and initialize the
            # 'pixels per metric' calibration variable
        (cnts, _) = contours.sort_contours(cnts)
        pixelsPerMetric = None

        object_num = 0
        r=object_num
        objects = []

        idx=0

        orig = image.copy()
        counter = 0
        leng = [0] * 400
        width = [0] *400
            # loop over the contours individually
        for c in cnts:
# if the contour is not sufficiently large, ignore it
            if cv2.contourArea(c) < 50:
                continue
                # compute the rotated bounding box of the contour
            box = cv2.minAreaRect(c)
            box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
            box = np.array(box, dtype="int")
                # order the points in the contour such that they appear
                # in top-left, top-right, bottom-right, and bottom-left
                 # order, then draw the outline of the rotated bounding box
            box = perspective.order_points(box)
            cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2)
            box.astype
                 # unpack the ordered bounding box, then compute the midpoint
                 # between the top-left and top-right coordinates, followed by
                 # the midpoint between bottom-left and bottom-right coordinates
            (tl, tr, br, bl) = box
            (tltrX, tltrY) = midpoint(tl, tr)
            (blbrX, blbrY) = midpoint(bl, br)
                 # compute the midpoint between the top-left and top-right points,
                 # followed by the midpoint between the top-righ and bottom-right
            (tlblX, tlblY) = midpoint(tl, bl)
            (trbrX, trbrY) = midpoint(tr, br)

                 # compute the Euclidean distance between the midpoints
            dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
            dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))

                 # if the pixels per metric has not been initialized, then
                 # compute it as the ratio of pixels to supplied metric (in this case, inches)
            if pixelsPerMetric is None:
                pixelsPerMetric = dB / 22.599 #previously its /22.50

                 # compute the size of the object
            area = round(cv2.contourArea(c) / (pixelsPerMetric**2), 3)
            perimeter = round(cv2.arcLength(c, True)/ pixelsPerMetric, 3)
            hull = cv2.convexHull(c)
            hull_area = round(cv2.contourArea(hull) / (pixelsPerMetric**2), 3)
            (x,y),(ma,MA),angle = cv2.fitEllipse(c)
            eccentricity = round(np.sqrt(1-(ma/MA)**2),3)
            C = round(4*np.pi*area/perimeter**2, 3)
            dimA = round(dA / pixelsPerMetric, 3)
            dimB = round(dB / pixelsPerMetric, 3)
            if (dimA >= dimB):
                temp=dimA
                dimA=dimB
                dimB=temp

            leng[counter] = str(dimB)
            width[counter] = str(dimA)
            counter = counter +1

            x,y,w,h = cv2.boundingRect(c)
            idx+=1
            mask = np.zeros(image.shape[:2],np.uint8)
            cv2.drawContours(mask, [c],-1, 255, -1)
            dst = cv2.bitwise_and(image, image, mask=mask)
            new_img=dst[y-20:y+h+20,x-20:x+w+20]

                # pre-process the image for classification
            if len(new_img) == 0:
                WB = 0
                continue

            object_num = object_num+1
            image1 = cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB)
            image1 = new_img.reshape((image1.shape[0] * new_img.shape[1], 3))

                #classify color
            clt.fit(image1)
            count = 0
            global dominant_color
            dominant_color = [0,0,0]

            for (color) in (clt.cluster_centers_):
                a = [color.astype("uint8").tolist()[0], color.astype("uint8").tolist()[1],
                 color.astype("uint8").tolist()[2]]
                count = count+1
                if(count == 2) and (a != [0, 0, 0]):
                    dominant_color = a

                #prepare image for broken classification
            new_img = cv2.resize(new_img, (64, 64))
            new_img = new_img.astype("float") / 255.0
            new_img = img_to_array(new_img)
            new_img = np.expand_dims(new_img, axis=0)

                # classify the input image
            with graph.as_default():

                (yes, no) = model.predict(new_img)[0]

                    # build the label
                if (yes > no):
                    WB = 0
                    y_new = "Broken"
                else:

                    if object_num == 1:
                        print("true")
                        continue
                    WB = 1
                    X_new = array([[dimA, dimB, area, perimeter, hull_area, eccentricity, C]])
                    X=sc.fit_transform(X)
                    X_new = sc.transform(X_new)
                    y_new = type_model.predict(X_new)
                    print("X=%s, Predicted=%s" % (X_new[0], y_new))

                    obj_num=object_num-1 # because one item on the left most side we have for the pixel constant value


                content = {
                    "Object_number": obj_num,
                    "Width": dimA,
                    "Length": dimB,
                    #"Area": area,
                    #"Perimeter": perimeter,
                    #"hull_area": hull_area,
                    #"eccentricity": eccentricity,
                    #"compactness": C,
                    "WB": WB # Whole or Broken
                    #"Type": str(y_new[0]),
                    #"color_rgb": dominant_color,
                    #"color_hex": rgb2hex(dominant_color[2], dominant_color[1], dominant_color[0])
                    }

                objects.append(content)

            return(objects)

        objects=analyze()
        with open('test6.json', 'w') as fout:
            json.dump(objects , fout)
        print(objects)
        print(type(objects))
        return 'ok'

Also in console only this 1 line gets printed:同样在控制台中,只有这 1 行被打印出来:

X=[ 0.38739663 -0.25583995  0.22674784 -0.2933872   0.19980647 -0.03758974
  0.4759277 ], Predicted=[4]

I'm returning this message to make sure that the JSON file is created but it doesn't gets created..I can't figure out what is wrong with the return type..kindly help.我返回此消息以确保创建了 JSON 文件,但没有创建它。我无法弄清楚返回类型有什么问题。请帮忙。

The views in Flask require a hashable return type. Flask 中的视图需要可散列的返回类型。 You can always convert your return values to hashable types viz string, dict, tuple etc and then transform from the result.您始终可以将返回值转换为可散列类型,即字符串、字典、元组等,然后根据结果进行转换。

return { "data": [ { "name": "my name", age: "27" } ] }

User oz19 commented用户oz19 评论

You need to serialize objects before returning.您需要在返回之前序列化objects import json and then json.dumps(objects)导入 json 然后json.dumps(objects)

and also 还有

You have a return(objects) at the end of for c in cnts .for c in cntsfor c in cnts末尾有一个return(objects) That could be the problem这可能是问题所在

So the solution if, not using jsonify , is to call json.dumps on the list before returning it.因此,如果不使用jsonify的解决方案是在返回列表之前调用json.dumps

If you are using this below method, you can easily get required data in json format如果您使用下面的方法,您可以轻松获得 json 格式的所需数据

# don't forgot to import jsonify

from flask import Flask, request, redirect, jsonify
@app.route('/sample', methods = ['GET', 'POST'])
def sample():
    if(request.method == 'GET'): # i am using get you can change whatever you want
        data = [{"A": "a",
                 "B": "b",
                 "C": "c",
               }]
        return jsonify({'data': data})
# now you can start your json dumping process here after

Hope it helps!希望能帮助到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 查看 function 未返回有效响应。 返回类型必须是字符串、字典、元组、响应实例或 WSGI 可调用,但它是一个列表 - view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a list TypeError:返回类型必须是字符串、字典、元组、响应实例或 WSGI 可调用的,但它是协程 - TypeError: The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a coroutine 返回类型必须是字符串、字典、元组、响应实例或可调用的 WSGI,但它是一个 TypeError - The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a TypeError python中的oracle查询-返回类型必须是字符串、字典、元组 - oracle query in python - The return type must be a string, dict, tuple 类型错误:在django 2.0中include()的情况下,视图必须是可调用的或列表/元组 - Type error:View must be a callable or a list/tuple in the case of include() in django 2.0 无法处理参数:int(1),它必须是 list、tuple 或 dict 类型 - Could not process parameters: int(1), it must be of type list, tuple or dict 类型错误:元组索引必须是整数,而不是元组 - Type error: Tuple indices must be integers, not tuple 类型错误“列表索引必须是整数或切片,而不是元组”(第6行) - Type error ' list indices must be integers or slices, not tuple' (line 6) 错误:Spider 必须返回 Request、BaseItem、dict 或 None,得到 'tuple' - ERROR: Spider must return Request, BaseItem, dict or None, got 'tuple' 在包含的情况下,视图必须是可调用的或列表/元组 - view must be a callable or a list/tuple in the case of include
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM