How to upload an Image File modified by OpenCV using FileSystemStorage in Django?

Question:

I am taking an uploaded image from the user and then sending it to a YOLO model which then returns me an image.

I want to store that returned image in my Local Directory and then display it on the user interface.

This is the Code of views.py that takes in an image and sends it to the Yolo Model,

def predictImage(request):
    # print(request)
    # print(request.POST.dict())
    fileObj = request.FILES['filePath']
    fs = FileSystemStorage()
    filePathName = fs.save(fileObj.name, fileObj)
    filePathName = fs.url(filePathName)
    testimage = '.'+filePathName
    # img = image.load_img(testimage, target_size=(img_height, img_width))
    img = detect_image(testimage)
    filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
    filePathName = fs.url(filePathName)

This is the function of YOLO Model that uses OpenCV to read the image (Image is sent as argument to the function) and then returns that image,

import numpy as np
import cv2

def detect_image(img_path):

    confidenceThreshold = 0.5
    NMSThreshold = 0.3

    modelConfiguration = 'cfg/yolov3.cfg'
    modelWeights = 'yolov3.weights'

    labelsPath = 'coco.names'
    labels = open(labelsPath).read().strip().split('n')

    np.random.seed(10)
    COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")

    net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)

    image = cv2.imread(img_path)
    (H, W) = image.shape[:2]

    #Determine output layer names
    layerName = net.getLayerNames()
    layerName = [layerName[i - 1] for i in net.getUnconnectedOutLayers()]

    blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
    net.setInput(blob)
    layersOutputs = net.forward(layerName)

    boxes = []
    confidences = []
    classIDs = []

    for output in layersOutputs:
        for detection in output:
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]
            if confidence > confidenceThreshold:
                box = detection[0:4] * np.array([W, H, W, H])
                (centerX, centerY,  width, height) = box.astype('int')
                x = int(centerX - (width/2))
                y = int(centerY - (height/2))

                boxes.append([x, y, int(width), int(height)])
                confidences.append(float(confidence))
                classIDs.append(classID)

    #Apply Non Maxima Suppression
    detectionNMS = cv2.dnn.NMSBoxes(boxes, confidences, confidenceThreshold, NMSThreshold)

    if(len(detectionNMS) > 0):
        for i in detectionNMS.flatten():
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])

            color = [int(c) for c in COLORS[classIDs[i]]]
            cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
            text = '{}: {:.4f}'.format(labels[classIDs[i]], confidences[i])
            cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
    
    return image 
    
    #cv2.imshow('Image', image)
    #cv2.waitKey(0)

On this line,

filePathName = fs.save(fileObj.name + "_result", img)

I am getting this following error,

'numpy.ndarray' object has no attribute 'read'

I am not sure how can I resolve this. I tried searching how can I store OpenCV Modified file usnig FileSystemStorage but found nothing of help. Can anyone help me regarding this?

Asked By: Awais Shahid

||

Answers:

You can use the imwrite function of cv2 library to store your files in the local directory, i.e.,

In your case, simply do this:

img = detect_image(testimage)
cv2.imwrite(fileObj.name+"_result.jpg", img=img) 
Answered By: Hassan Ashas