OpenCV2 imwrite is writing a black image

Viewed 7805

I am messing around with opencv2 for neural style transfer... In cv2.imshow("Output", output), I am able to say my picture. But when I write output to file with cv2.imwrite("my_file.jpg", output). Is it because my file extension is wrong? When I do like cv2.imwrite("my_file.jpg", input) though, it does show my original input picture. Any ideas? Thank you in advance.

# import the necessary packages
from __future__ import print_function
import argparse

import time
import cv2
import imutils

import numpy as np
from imutils.video import VideoStream

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-m", "--model", required=True,
    help="neural style transfer model")
ap.add_argument("-i", "--image", required=True,
    help="input image to apply neural style transfer to")

args = vars(ap.parse_args())

# load the neural style transfer model from disk
print("[INFO] loading style transfer model")
net = cv2.dnn.readNetFromTorch(args["model"])

# load the input image, resize it to have a width of 600 pixels, and
# then grab the image dimensions
image = cv2.imread(args["image"])
image = imutils.resize(image, width=600)
(h, w) = image.shape[:2]

# construct a blob from the image, set the input, and then perform a
# forward pass of the network
blob = cv2.dnn.blobFromImage(image, 1.0, (w, h),
    (103.939, 116.779, 123.680), swapRB=False, crop=False)
net.setInput(blob)
start = time.time()
output = net.forward()
end = time.time()

# reshape the output tensor, add back in the mean subtraction, and
# then swap the channel ordering
output = output.reshape((3, output.shape[2], output.shape[3]))
output[0] += 103.939
output[1] += 116.779
output[2] += 123.680
output /= 255.0
output = output.transpose(1, 2, 0)

# show information on how long inference took
print("[INFO] neural style transfer took {:.4f} seconds".format(
    end - start))

# show the images
cv2.imshow("Input", image)
cv2.imshow("Output", output)
cv2.waitKey(0)
cv2.imwrite("dogey.jpg", output)

Only the last 4 lines of code have to deal with imshow and imwrite, all lines before are trying to modify the output picture.

1 Answers

The variable output represents a colored image that is composed of pixels. Each pixel is determined by three values (RGB). Depending on the representation of the image each value is chosen from the discrete range [0, 255] or continuous range [0, 1] either. However, in the following line of code, you are scaling the entries of output from the discrete range [0,255] to the "continuous" range [0,1].

output /= 255.0

While the function cv2.imshow(...) can handle images stored with float values in the range [0, 1] the cv2.imwrite(...) function cannot. You have to pass an image composed of values in the range [0, 255]. In your case, you are passing values that are all close to zero and "far" away from 255. Hence, the image is assumed as colorless and therefore black. A quick fix might be:

cv2.imwrite("dogey.jpg", 255*output)
Related