In this tutorial, you will learn how to apply neural style transfer to both images and real-time video using OpenCV, Python, and deep learning. By the end of this guide, you’ll be able to generate beautiful works of art with neural style transfer.
The original neural style transfer algorithm was introduced by Gatys et al. in their 2015 paper, A Neural Algorithm of Artistic Style (in fact, this is the exact algorithm that I teach you how to implement and train from scratch inside Deep Learning for Computer Vision with Python).
In 2016, Johnson et al. published Perceptual Losses for Real-Time Style Transfer and Super- Resolution, which frames neural style transfer as a super-resolution-like problem using perceptual loss. The end result is a neural style transfer algorithm which is up to three orders of magnitude faster than the Gatys et al. method (there are a few downsides though and I’ll be discussing them later in the guide).
In the rest of this post you will learn how to apply the neural style transfer algorithm to your own images and video streams.
To learn how to apply neural style transfer using OpenCV and Python, just keep reading!
Looking for the source code to this post?
Jump Right To The Downloads SectionNeural Style Transfer with OpenCV
In the remainder of today’s guide I will be demonstrating how you can apply the neural style transfer algorithm using OpenCV and Python to generate your own works of art.
The method I’m discussing here today is capable of running in near real-time on a CPU and is fully capable of obtaining super real-time performance on your GPU.
We’ll start with a brief discussion of neural style transfer, including what it is and how it works.
From there we’ll utilize OpenCV and Python to actually apply neural style transfer.
What is neural style transfer?
Neural style transfer is the process of:
- Taking the style of one image
- And then applying it to the content of another image
An example of the neural style transfer process can be seen in Figure 1. On the left we have our content image — a serene view of myself enjoying a beer on top of a mountain in the Black Forest of Germany, overlooking the town of Baden.
In the middle is our style image, Vincent van Gogh’s famous The Starry Night.
And on the right is the output of applying the style of van Gogh’s Starry Night to the content of my photo of Germany’s Black Forest. Notice how we have retained the content of the rolling hills, forest, myself, and even the beers, but have applied the style of Starry Night — it’s as if Van Gogh had applied his masterful paint strokes to our scenic view!
The question is, how do we define a neural network to perform neural style transfer?
Is that even possible?
You bet it is — and we’ll be discussing how neural style transfer is made possible in the next section.
How does neural style transfer work?
At this point you’re probably scratching your head and thinking something along the lines of: “How do we define a neural network to perform style transfer?”
Interestingly, the original 2015 paper by Gatys et al. proposed a neural style transfer algorithm that does not require a new architecture at all. Instead, we can take a pre-trained network (typically on ImageNet) and define a loss function that will enable us to achieve our end goal of style transfer and then optimize over that loss function.
Therefore, the question isn’t “What neural network do we use?” but rather “What loss function do we use?”
The answer is a three-component loss function, including:
- Content loss
- Style loss
- Total-variation loss
Each component is individually computed and then combined in a single meta-loss function. By minimizing the meta-loss function we will be in turn jointly optimizing the content, style, and total-variation loss as well.
While the Gatys et al. method produced beautiful neural style transfer results, the problem was that it was quite slow.
Johnson et al. (2016) built on the work of Gatys et al., proposing a neural style transfer algorithm that is up to three orders of magnitude faster. The Johnson et al. method frames neural style transfer as a super-resolution-like problem based on perceptual loss functions.
While the Johnson et al. method is certainly fast, the biggest downside is that you cannot arbitrarily select your style images like you could in the Gatys et al. method.
Instead, you first need to explicitly train a network to reproduce the style of your desired image. Once the network is trained, you can then apply it to any content image you wish. You should see the Johnson et al. method as a more of an “investment” in your style image — you better like your style image as you’ll be training your own network to reproduce its style on content images.
Johnson et al. provide documentation on how to train your own neural style transfer models on their official GitHub page.
Finally, it’s also worth noting that that in Ulyanov et al.’s 2017 publication, Instance Normalization: The Missing Ingredient for Fast Stylization, it was found that swapping batch normalization for instance normalization (and applying instance normalization at both training and testing), leads to even faster real-time performance and arguably more aesthetically pleasing results as well.
I have included both the models used by Johnson et al. in their ECCV paper along with the Ulyanov et al. models in the “Downloads” section of this post — be sure to download them so you can follow along with the remainder of this guide.
And if you’re interested in learning more about how neural style transfer works, be sure to refer to my book, Deep Learning for Computer Vision with Python.
Project structure
Today’s project includes a number of files which you can grab from the “Downloads” section.
Once you’ve grabbed the scripts + models + images, you can inspect the project structure with the tree
command:
$ tree --dirsfirst . ├── images │ ├── baden_baden.jpg │ ├── giraffe.jpg │ ├── jurassic_park.jpg │ └── messi.jpg ├── models │ ├── eccv16 │ │ ├── composition_vii.t7 │ │ ├── la_muse.t7 │ │ ├── starry_night.t7 │ │ └── the_wave.t7 │ └── instance_norm │ ├── candy.t7 │ ├── feathers.t7 │ ├── la_muse.t7 │ ├── mosaic.t7 │ ├── starry_night.t7 │ ├── the_scream.t7 │ └── udnie.t7 ├── neural_style_transfer.py ├── neural_style_transfer_examine.py └── neural_style_transfer_video.py 4 directories, 18 files
Once you use the “Downloads” section of the blog post to grab the .zip, you won’t need to go hunting for anything else online. I’ve provided a handful of test images/
as well as a number of models/
that have already been trained by Johnson et. al. You’ll also find three Python scripts to work with and we’ll be reviewing two of them today.
Implementing neural style transfer
Let’s get started implementing neural style transfer with OpenCV and Python.
Open up your neural_style_transfer.py
file and insert the following code:
# import the necessary packages import argparse import imutils import time import cv2 # 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())
First, we import our required packages and parse command line arguments.
Our notable imports are:
- imutils: This package is pip-installable via
pip install --upgrade imutils
. I recently releasedimutils==0.5.1
, so don’t forget to upgrade! - OpenCV: You need OpenCV 3.4 or better in order to use today’s code. You can install OpenCV 4 using my tutorials for Ubuntu and macOS.
We have two required command line arguments for this script:
--model
: The neural style transfer model path. I’ve included 11 pre-trained models for you to use in the “Downloads”.--image
: Our input image which we’ll apply the neural style to. I’ve included 4 sample images. Feel free to experiment with your own as well!
You do not have to change the command line argument code — the arguments are passed and processed at runtime. If you aren’t familiar with how this works, be sure to read my command line arguments + argparse blog post.
Now comes the fun part — we’re going to load our image + model and then compute neural style transfer:
# 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()
In this code block we proceed to:
- Load a pre-trained neural style transfer model into memory as
net
(Line 17). - Load the input
image
and resize it (Lines 21 and 22). - Construct a
blob
by performing mean subtraction (Lines 27 and 28). Read aboutcv2.dnn.blobFromImage
and how it works in my previous blog post. - Perform a
forward
pass to obtain anoutput
image (i.e., the result of the neural style transfer process) on Line 31. I’ve also surrounded this line with timestamps for benchmarking purposes.
Next, it is critical that we post-process the output
image:
# 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)
For the particular image I’m using for this example, the output
NumPy array will have the shape (1, 3, 452, 600)
:
- The
1
indicates that we passed a batch size of one (i.e., just our single image) through the network. - OpenCV is using channels-first ordering here, indicating there are
3
channels in the output image. - The final two values in the output shape are the number of rows (height) and number of columns (width).
We reshape the matrix to simply be (3, H, W)
(Line 36) and then “de-process” the image by:
- Adding back in the mean values we previously subtracted (Lines 37-39).
- Scaling (Line 40).
- Transposing the matrix to be channels-last ordering (Line 41).
The final step is to show the output of the neural style transfer process to our screen:
# 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)
Neural style transfer results
In order to replicate my results, you will need to grab the “Downloads” for this blog post.
Once you’ve grabbed the files, open up terminal and execute the following command:
$ python neural_style_transfer.py --image images/giraffe.jpg \ --model models/eccv16/the_wave.t7 [INFO] loading style transfer model... [INFO] neural style transfer took 0.3152 seconds
Now, simply change the command line arguments to use a screen capture from my favorite movie, Jurassic Park, as the content image, and then The Scream style model:
$ python neural_style_transfer.py --image images/jurassic_park.jpg \ --model models/instance_norm/the_scream.t7 [INFO] loading style transfer model... [INFO] neural style transfer took 0.1202 seconds
And changing the command line arguments in your terminal once more:
$ python neural_style_transfer.py --image images/messi.jpg \ --model models/instance_norm/udnie.t7 [INFO] loading style transfer model... [INFO] neural style transfer took 0.1495 seconds
Figure 5 is arguably my favorite — it just feels like it could be printed and hung on a wall in a sports bar.
In these three examples, we’ve created deep learning art! In the terminal output, the time elapsed to compute the output image is shown — each CNN model is a little bit different and you should expect different timings for each of the models.
Challenge! Can you create fancy deep learning artwork with neural style transfer? I’d love to see you tweet your artwork results — just use the hashtag, #neuralstyletransfer and mention me in the tweet (@PyImageSearch). Also, be sure to give credit to the artists and photographers — tag them if they are on Twitter as well.
Real-time neural style transfer
Now that we’ve learned how to apply neural style transfer to single images, let’s learn how to apply the process to (near) real-time video as well.
The process is quite similar to performing neural style transfer on a static image. In this script, we’ll:
- Utilize a special Python iterator which will allow us to cycle over all available neural style transfer models in our
models
path. - Start our webcam video stream — our webcam frames will be processed in (near) real-time. Slower systems may lag quite a bit for certain larger models.
- Loop over incoming frames.
- Perform neural style transfer on the frame, post-process the output, and display the result to the screen (you’ll recognize this from above as it is nearly identical).
- If the user presses the “n” key on their keyboard, we’ll utilize the iterator to cycle to the next neural style transfer model without having to stop/restart the script.
Without further ado, let’s get to it.
Open up your neural_style_transfer_video.py
file and insert the following code:
# import the necessary packages from imutils.video import VideoStream from imutils import paths import itertools import argparse import imutils import time import cv2 # construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-m", "--models", required=True, help="path to directory containing neural style transfer models") args = vars(ap.parse_args())
We begin by importing required packages/modules.
From there, we just need the path to our models/
directory (a selection of models is included with today’s “Downloads”). The command line argument, --models
, coupled with argparse
, allows us to pass the path at runtime.
Next, let’s create our model path iterator:
# grab the paths to all neural style transfer models in our 'models' # directory, provided all models end with the '.t7' file extension modelPaths = paths.list_files(args["models"], validExts=(".t7",)) modelPaths = sorted(list(modelPaths)) # generate unique IDs for each of the model paths, then combine the # two lists together models = list(zip(range(0, len(modelPaths)), (modelPaths))) # use the cycle function of itertools that can loop over all model # paths, and then when the end is reached, restart again modelIter = itertools.cycle(models) (modelID, modelPath) = next(modelIter)
Once we begin processing frames in a while
loop (to be covered in a few code blocks), a “n” keypress will load the “next” model in the iterator. This allows you to see the effect of each neural style model in your video stream without having to stop your script, change your model path, and then restart.
To construct our model iterator, we:
- Grab and sort paths to all neural style transfer models (Lines 18 and 19).
- Assign a unique ID to each (Line 23).
- Use
itertools
andcycle
to create an iterator (Line 27). Essentially,cycle
allows us to create a circular list which when you reach the end of it, starts back at the beginning.
Calling the next
method of the modelIter
grabs our first modelID
and modelPath
(Line 28).
If you are new to Python iterators or iterators in general (most programming languages implement them), then be sure to give this article by RealPython a read.
Let’s load the first neural style transfer model and initialize our video stream:
# load the neural style transfer model from disk print("[INFO] loading style transfer model...") net = cv2.dnn.readNetFromTorch(modelPath) # initialize the video stream, then allow the camera sensor to warm up print("[INFO] starting video stream...") vs = VideoStream(src=0).start() time.sleep(2.0) print("[INFO] {}. {}".format(modelID + 1, modelPath))
On Line 32, we read the first neural style transfer model using its path.
Then on Lines 36 and 37, we initialize our video stream so we can grab frames from our webcam.
Let’s begin looping over frames:
# loop over frames from the video file stream while True: # grab the frame from the threaded video stream frame = vs.read() # resize the frame to have a width of 600 pixels (while # maintaining the aspect ratio), and then grab the image # dimensions frame = imutils.resize(frame, width=600) orig = frame.copy() (h, w) = frame.shape[:2] # construct a blob from the frame, set the input, and then perform a # forward pass of the network blob = cv2.dnn.blobFromImage(frame, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False) net.setInput(blob) output = net.forward()
Our while
loop begins on Line 41.
Lines 43-57 are nearly identical to the previous script we reviewed with the only exception being that we load a frame from the video stream rather than an image file on disk.
Essentially we grab the frame
, preprocess it into a blob
, and send it through the CNN. Be sure to refer to scroll up to my previous explanation if you didn’t read it already.
There’s a lot of computation going on behind the scenes here in the CNN. If you’re curious how to train your own neural style transfer model with Keras, be sure to refer to my book, Deep Learning for Computer Vision with Python.
Next, we’ll post-process and display the output
image:
# 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 the original frame along with the output neural style # transfer cv2.imshow("Input", frame) cv2.imshow("Output", output) key = cv2.waitKey(1) & 0xFF
Again, Lines 61-66 are identical to the static image neural style script above where I explained these lines in detail. These lines are critical to you seeing the correct result. Our output image is “de-processed” by reshaping, mean addition (since we subtracted the mean earlier), rescaling, and transposing.
The output of our neural style transfer is shown on Lines 70 and 71, where both the original and processed frames are displayed on the screen.
We also capture keypresses on Line 72. The keys are processed in the next block:
# if the `n` key is pressed (for "next"), load the next neural # style transfer model if key == ord("n"): # grab the next neural style transfer model model and load it (modelID, modelPath) = next(modelIter) print("[INFO] {}. {}".format(modelID + 1, modelPath)) net = cv2.dnn.readNetFromTorch(modelPath) # otheriwse, if the `q` key was pressed, break from the loop elif key == ord("q"): break # do a bit of cleanup cv2.destroyAllWindows() vs.stop()
There are two keys that will cause different behaviors while the script is running:
- “n”: Grabs the “next” neural style transfer model path + ID and loads it (Lines 76-80). If we’ve reached the last model, the iterator will cycle back to the beginning.
- “q”: Pressing the “q” key will “quit” the
while
loop (Lines 83 and 84).
Cleanup is then performed on the remaining lines.
Real-time neural style transfer results
Once you’ve used the “Downloads” section of this tutorial to download the source code and neural style transfer models, you can execute the following command to apply style transfer to your own video streams:
$ python neural_style_transfer_video.py --models models
As you can see, it’s easy to cycle through the neural style transfer models using a single keypress.
I have included a short demo video of myself applying neural transfer below:
What's next? We recommend PyImageSearch University.
86+ total classes • 115+ hours hours of on-demand code walkthrough videos • Last updated: January 2025
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 86+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 86 Certificates of Completion
- ✓ 115+ hours hours of on-demand video
- ✓ Brand new courses released regularly, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 540+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
Summary
In today’s blog post you learned how to apply neural style transfer to both images and video using OpenCV and Python.
Specifically, we utilized the models trained by Johnson et al. in their 2016 publication on neural style transfer — for your convenience, I have included the models in the “Downloads” section of this blog post.
I hope you enjoyed today’s tutorial on neural style transfer!
Be sure to use Twitter and the comments section to post links to your own beautiful works of art — I can’t wait to see them!
To be notified when future blog posts are published here on PyImageSearch, just enter your email address in the form below!
Download the Source Code and FREE 17-page Resource Guide
Enter your email address below to get a .zip of the code and a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!
Huy Ngo
Absolutely amazing tutorial, Adrian! Thank you for doing this!
Adrian Rosebrock
Thanks Huy Ngo, I’m so happy you liked the guide! Have fun with it 🙂
Ritika Agarwal
Awesome tutorial!!
Adrian Rosebrock
Thanks Ritika! 🙂
Mark West
Great post! Even though I know this will run *very* slowly on a Raspberry Pi 3 B+ I’m stil tempted to give it a try!
Adrian Rosebrock
It will run slower for sure, but it will still work. You could at the very least still apply it to single images.
nisar
can you provide source guide for vehicle automation?
Adrian Rosebrock
Vehicle automation is a pretty big area, far more than what could be covered in a single blog post. Perhaps if you could be a bit more specific?
holger
Wow – i really really liked the jurassic park picture 🙂
“…fully capable of obtaining super real-time performance on your GPU…”
I want to have this – this would mean running the model directly on torch(with gpu support enabled) – right? Open cv has no cuda support and open cl / halide also ist no big help imho.
Adrian Rosebrock
The Jurassic Park one is my favorite as well! You could run the model directly via Torch but I also know that OpenCV is working on Python + CUDA bindings. Once those are available I will be sharing how to use them.
Romie
Hi Adrian,
This tutorial was amazing! Thorough and evolving. I was hoping to get this going using my GPU and was wondering if you had looked into that yet. Thanks again!
Adrian Rosebrock
OpenCV’s “dnn” module still does not support NVIDIA GPUs, so no, it’s not really possible.
Walid
Worked great as usual
My question is , how can I show the style image too besides the original and the output
Thanks a lot
Walid
Adrian Rosebrock
The networks used in this example were actually pre-trained using the style image so you can’t actually “show” the style image unless you wanted to explicitly save it to disk and then show it when executing. I have included links to each of the respective works of art in the post though 🙂
Aldo
Great post Adrian!
I have a question, how can I get more models in ‘.t7’ extension?
Adrian Rosebrock
You would need to train your own model. Be sure to refer to the official repo for the author’s paper.
Juan
Hi Adrian! very good post! I have a question regarding the paintings that are used as a base in the neural network, is it possible to change them? Is the retraining of the model necessary with each one? thank you very much!
Adrian Rosebrock
If you wanted to use a different style image you would need to train the network from scratch. This behavior is one of the downsides of the Johnson et al. method to neural style transfer. The original Gatys et al. method allowed you to supply your style and content images on the fly (but would take longer to perform the transfer).
qiang92
Why don’t you use enumerate(models) instead of zip(range(0, len(modelPaths)), (modelPaths)))
secondaria
Adrian Rosebrock, thank you for your blog post.Really thank you! Awesome.
Adrian Rosebrock
Thanks so much, I’m so happy to hear you enjoyed the tutorial! 🙂
yueyu
How do I know which models of OpenCV DNN support? I can’t see that it supports style migration model again
Adrian Rosebrock
The OpenCV docs actually mention which layer types are supported, tips on migrating networks, etc.
Mark C
This looks great i did some generative neural network and it is really cool.
Adrian Rosebrock
Nice job, Mark!
atom
Great post again, Mr Incredible!
One odd wonder around reason you trained networks using torch instead others
Adrian Rosebrock
I actually didn’t train the networks. The networks were trained by Johnson et al.
Karla
Excellent tutorial, congratulations!!
One question, how can we save the output image?
I’ve been trying to do so, but as float32 ndarray, imwrite function does not display the same result as imshow. The conversion to uint8 (in order to save the image to disk) makes the colors from the saved image completely different to the ones seen in the image of the output window.
Thanks in advance!
Karla
Adrian Rosebrock
Interesting — I just replicated the same error as well. I’m traveling for PyImageConf right now so I can’t provide a solution but in the meantime I would suggest posting on the official OpenCV GitHub page to see if this is a known bug or if there is a workaround.
Karla
Thank you for attempting a quick try Adrian, I’ll try to come back with a solution. Have fun at PyImageConf! 🙂
Adrian Rosebrock
Thanks Karla!
Taha Anwar
So here is a simple solution Adrian,
I have modified some lines above and now pasting those lines below:
output[0] += 103.939
output[1] += 116.779
output[2] += 123.680
output = output.transpose(1, 2, 0)
output = np.clip(output, 0, 255)
output= output.astype(‘uint8’)
# show information on how long inference took
print(“neural style transfer took {:.2f} seconds”.format(end – start))
#so the solution is to drop the 255 division and convert it to uint8 but before that you also have to clip the negative and 255+ values to avoid a messy image
Adrian Rosebrock
Thanks for sharing, Taha!
kaisar khatak
Any luck finding a solution? Writing video out simply generates black output frames…
output_movie.write(output.astype(np.uint8))
Thanks.
Bill Strum
I have the same issue. perfect images with imshow and color errors when converted to file format.
I use output = (output * 255).astype(np.uint8) to rescale the numpy data and then
cv2.imwrite(path + “/” + “Test_Out” + ‘.jpg’, output)
I get color artifacts in the .jpg file I cant explain Did you resolve the problem?
Grant Hodgson
Getting rid of the part where output is divided by 255.0 worked for me. I believe it is line 44.
This answer may be helpful: https://stackoverflow.com/questions/10571874/opencv-imwrite-saving-complete-black-jpeg
Toni
Nice Tutorial Adrian.
Can we save output results as a png or jpg file ? cv2.imwrite function produces empty files.
Thanks a lot,
Toni
Adrian Rosebrock
See my reply to Karla — I would appreciate if other PyImageSearch readers could look into it as well 🙂
Arthur Dehls
I wonder how many total hours people bashed their heads before they noticed that the quotes that Karla used are different from the standard ones. Cutting and pasting wrong characters that look right… ouch! The joy of coding… pages and pages of code with one , that should be a .
Big Adam
Thank you for the great tutorial.
I am confused about line 40, why do we scale the values?
Karla
The output is a Numpy array with values within the [0-1] range, and so we convert the color scale to [0-255] range for RGB values, since this is the range for each individual color (8-bit Red, Green, Blue). By dividing by 255, the [0-255] range can be described with a [0.0-1.0] range where 0.0 means 0 (0x00) and 1.0 means 255 (0xFF).
BMSuser
output *= 255.0
cv2.imwrite(“saved.png”, output)
Z Abrams
Cool post!
Any chance you can explain/link-to how we can create a model using Keras (TF backend, like in your book), and then use that instead of a .t7 Torch file? I see that OpenCV has a readNetFromTensorflow , so is there a way to save the model and then reload it?
[I’ve heard Tensorflow is “slower” than Caffe/Torch, but let’s forget that for now.]
Also, I assume the speed is Network dependent, so basing it off a VGG16/19 seems a bit overkill considering newer, leaner models (mobilenet/googlenet/etc).There’s no reason these things shouldn’t be <5MB, like ENet.
Adrian Rosebrock
You can’t use this code directly for a Keras-trained model. You would need to swap out the OpenCV model loading code for the Keras code and then apply it directly to the images/frames. The OpenCV + TensorFlow model loading functionalities are getting better, but they’re not quite there (in my opinion). You’re better off using strict TensorFlow or strict Keras to load a model and classify an image/frame than trying to make it work with OpenCV.
Abhishek Singh
Hey Adrian, Any help here?
python neural_style_transfer.py –image images/giraffe.jpg \
> –model models/eccv16/the_wave.t7
[INFO] Importing Neural Style Model
Traceback (most recent call last):
File “neural_style_transfer.py”, line 15, in
net = cv2.dnn.readNetFromTorch(args[“model”])
AttributeError: ‘module’ object has no attribute ‘dnn’
Adrian Rosebrock
It sounds like you’re using an older version of OpenCV. What version of OpenCV are you using? I recommend OpenCV 3.4.1 or newer for this post.
jorge
Hi Adrian great post!
I would like to save the modified image using cv2.imwrite(‘famMod.jpg’,output) at the end of the script but the file saved didn’t show anything.
You know why.
Adrian Rosebrock
Make sure you read the comments section. In particular, my reply to Karla.
Tracy
Is there a way for me to try this out without buying the book?
Adrian Rosebrock
Hey Tracy — I’m not sure what you mean regarding buying my book. You don’t have to buy anything if you don’t want. Just use the “Downloads” section of the blog post to download my source code and example images.
J Serena
Hello Adrian,
I starter with Machine Learning few months ago and your articles have been the lighthouse that guided me.
I hope you will be writing so interesting articles for a long time.
Adrian Rosebrock
Thank you for the kind words, I really appreciate it 🙂
Raj
Thanks Adrian. All the articles here are brilliant. I really helps me understand the concepts and applications since I am a newbie in this field.
Adrian Rosebrock
Thanks Raj, I’m happy you are enjoying the tutorials 🙂 And congratulations on getting your start in computer vision and deep learning.
nettoyer
Hello Adrian, there is my image saving workaround via ‘imageio’:
import imageio
…
output = cv2.cvtColor(output, cv2.COLOR_BGR2RGB)
imageio.imwrite(‘output.jpg’, output)
P.S.
many thanks for your great example that push to learn this area
Adrian Rosebrock
Thanks so much for sharing!
Alex
Thank you all very much. Also trying to save – but gives an error
–
WARNING:root:Lossy conversion from float32 to uint8.
Deepak
Can u write a blog on self driving car
Basically Lane following raspberry pi car
Stop detector,red light etc
Marco Heimeshoff
This is wonderful. How do I activate the GPU though, right now it is just running on the processor.
I have a Windows 10 64bit machine with a GTX1060 and Cuda is installed, if that helps
Adrian Rosebrock
Make sure you see my reply to Jim.
Jim
How to use GPU acceleration with this Python code? I’ve install CUDA and numba, as this video https://www.youtube.com/watch?v=vMZ7tK-RYYc has told. While, when I running the code, I found my GPU still not occupied.
Thanks a lot!
Adrian Rosebrock
Unfortunately at this time you cannot use CUDA acceleration via Python. I suspect support is coming soon but it’s not there yet.
Eon Kim
Thanks Adrian. Your articles are very helpful to me. I have a question. What is the license for this code? Can I correct this code and push it on the github?
Adrian Rosebrock
Yes, but I would appreciate an attribution with a link back to the blog post.
Victor Aregbede
Hey Andrian please can this be run on google colab.
Richard Andrews
HI Adrian,
I have been trying to create models for other styles. I installed lua, torch and all the dependencies.
Keep getting new errors.
A bunch of them.
I’m running this on MacOS.
Is there a better way to create new models???
Desperately need help sadly. :-((((
This has been the worst nightmare.
Adrian Rosebrock
I’m sorry you’ve ran into a bunch of issues, Richard. I cover how to create your own custom neural style transfer images inside Deep Learning for Computer Vision with Python. That would be my recommended starting point.
Cao An
Hi Adrian thanks for this tutorial! Is there a way to do guided style transfer easily from your code?
Sahil Makwane
Hey Adrian,
For the last 48 hours, I’d been banging my head on the keyboard (literally) trying to get Neural Style Transfer to work. I went through about 20 github projects and nearly every youtube video on the search result, with no luck. I’m new to this and the module errors or runtime errors just kept piling up. I finally fell upon your tutorial. Spent diligent time trying to go step by step; and FINALLY, IT WORKED. You’ve provided me a base for a final year project i’m supposed to pursue as an undergrad student. I CAN’T THANK YOU ENOUGH. You’re a savior. THANK YOU SO MUCH!
Adrian Rosebrock
That’s awesome Sahil! Good luck with your final year project.
Veronica
Hey Adrian,
Awesome tutorial! Really cool and a great way to start to get into more computer vision applications. You mentioned Twitter above but can I assume that if I used this code to generate images (and with some additions, videos) and post to Instagram and tag pyimagesearch in the post that you’d be okay with it?
Adrian Rosebrock
Absolutely, feel free to do so!
Bill Strum
I have the same question as Karla, how do I save output in a standard image file format?
I tried the PIL from array and that gave an all black image.
I have built a GUI and want to display output.
I think this would be useful info to a broad audience
Bill Strum
The issue of getting images to save and display correctly comes from the following.
There is a difference between OpenCV addition and Numpy addition. OpenCV addition is a saturated operation while Numpy addition is a modulo operation.
My original code for re-scaling was :
output = (output * 255).astype(np.uint8)
This causes error due to truncation and wrap around.
The code that works clamps the range to prevent saturation:
output = np.clip(output * 255, 0, 255) # proper [0..255] range
output = output.astype(np.uint8) # safe conversion
The images saved and displayed are now identical to the imshow(0 versions
Adrian Rosebrock
Great catch, thanks for sharing Bill!