10 – Coding A Blue Screen

Let’s code up a simple blue screen color selection in Python. We’ll be using a new library in this lesson called OpenCV, which is commonly used in computer vision applications and will help us create custom applications of our own. We’ll be starting with an image of a pizza on a blue screen background. We’ll first have to identify this blue region, then later we’ll replace it with a background image of our choosing. Here’s our Python notebook and my first step is to import the libraries I need and we’ll use these throughout this lesson. For plotting I’ll import pyplot from matplotlib and for operating on an image I’ll use numpy and the computer vision library OpenCV which is named cv2. Next, I’ll read in the image of the pizza using cv2.imread. The image is named pizza_ bluescreen.jpg and it’s in the same directory as this notebook in a folder named “images”. Once it’s read in, you may want to print out some information about the image. This is often helpful to see before starting to manipulate any image. So I’ll print out what type of data it is and I expect it to be a 2D array, also known as a grid or matrix of pixel values. And I’ll also print its shape which will tell us the dimensions of the image. Then let’s run this and we see the expected output. The image is indeed an array and its shape contains three values that represent the dimensions of the image array. First its height 514 pixels, then its width 816, and finally how many color components it has: in this case three, for red, green and blue values. Next I’ll display this image using pyplot. But we can see that the image looks weird, that the background is red and not blue like we expect. So what’s happening here? Well, OpenCV reads in color images as BGR (blue, green, red) images and not RGB. So the red and blue colors are in reverse order and pyplot reflects this switch. You can learn more about why OpenCV does this in text. But for this and many other examples I’ll often change images from BGR to RGB because they’ll will be easier to display. So before we display the image let’s make a copy of the original image and use OpenCV to change the color from BGR to RGB. It’s good practice to always make a copy of the image you’re working with. This way any transformation you’ll apply to the copy will not affect the original image, so it’s easier to undo a step or try something new. And I’ll name this copy image_copy. Then on this copy we can perform a color transformation using the OpenCV function cvtColor. This takes in a source image and color conversion code which in this case is just BGR to RGB, and then outputs the desired image. Then if we plot this image copy we see the blue screen background as expected. I went through this image reading, copying and displaying code fairly slowly this time, because we’ll be using it regularly. But now let’s jump into the blue screen color threshold code. To create a color threshold, I’ll first define lower and upper bounds for the color I want to isolate – blue. I want to use these values to eventually select the blue screen area that contains this range of color values and get rid of it. So I’ll define a lower threshold that contains the lowest values of red, green and blue that are still considered part of the blue screen background. This will be an array of three values. For red and green, I’ll set this as 0 meaning it’s okay to have no red or green. But the lowest value for blue should still be quite high. Now all the way up to 255, but let’s say around 230. Similarly, I’ll define the upper threshold. I’ll define it to allow a little more red and green, say 50 each, and I’ll set the highest value for blue to be 255. Any color within this low and high range will be an intense blue color. I’m doing some estimation though so if I find that this range isn’t finding the blue screen area that I want, I’ll come back and change these values. Next, I’ll use the color bounds I just created to create an image mask. Masks are a very common way to isolate a selected area of interest and do something with that area. We can create a mask over the blue area using OpenCVs in inRange function. This function takes in an image in our lower and upper color bounds and defines a mask by asking if the color value of each image pixel falls in the range of the lower and upper color thresholds. If it does fall in this range, the mask will allow it to be displayed and if not it will block it out and turn the pixel back. In fact, we can visualize the mask by plotting it as we would an image. This white area is where the image will be allowed to show through and the black will be blocked out. In numerical values, we can look at this mask as a 2D grid with the same dimensions as our image; 514 pixels in height and 816 in width. And each coordinate in this mask has a value of either 255 for white or 0 for black, sort of like a grayscale image. And when we look at this mask we can see that it has a white area where the blue screen background is and a black area where the pizza is. And the first thing we want to do is let the pizza show through and block the blue screen background. First, to mask the image I’ll make another image copy called masked image of our color changed image copy, just in case I want to change the mask later on. Then one way to select the blue screen area is by asking for the part of that image that overlaps with the part of the mask that is white or not black. That is, we’ll select the part of the image where the area of the mask is not equal to zero, using this exclamation point equals boolean operator, where the exclamation point means not. And to block this background area out we then set these pixels to black. In RGB black is just zeros for all three color values. Then when we display our image we should see that the pizza area is the only area that shows through; the blue screen background is gone. I might even change my color thresholds to get rid of these last few spots. I’ll try increasing my highest green value to 70 and decreasing my low blue value to 220. This should capture a larger range of blue. Then I’ll run the masking and displaying code again. And this image looks even better. Now we just have one last step which is to apply a background to this image. The process will be fairly similar so I’ll go through these steps fairly quickly. First, I’ll read in an image of outer space and convert it to RGB color. I’ll also crop it so that it’s the same size as our pizza image; 514 by 816 pixels. I’m calling this image crop_background. Then I’ll apply the mask, this time using the opposite mask, meaning I want the background to show through and not the Pizza area. If we look back at the mask in this case I’m blocking the part of the background image where the mask is equal to zero. And for this we say mask == 0. Just to make sure I got this masking correct, I’ll plot the resulting image and I get the background with the pizza cut out. Then finally I just need to add these two images together. Since the black area is equivalent to zeros in pixel color value, a simple addition will work. And when I plot the complete image I get a pizza floating in space. And that’s it. In text you’ll find notes on the functions we use to get here. And next you’ll get some hands on practice coding your own color threshold.

%d 블로거가 이것을 좋아합니다: