Remove green screen from a image and make it transparent - python

I found a solution to this but the background is not transparent, it's black and I don't know how I should make it transparent.
Here's my code:
from PIL import Image
image = Image.open('pic.jpg')
image.show()
image_data = image.load()
height,width = image.size
for loop1 in range(height):
for loop2 in range(width):
r,g,b = image_data[loop1,loop2]
image_data[loop1,loop2] = r,0,b
image.save('changed.png')

If your background consists of one color, then you can replace it with transparent in the following way:
from PIL import Image
img = Image.open('pic.png')
rgba = img.convert('RGBA')
data = rgba.getdata()
green_rgb = (0, 128, 0) # change it to your exact bg color
new_data = [item if item[:-1] != green_rgb else (255, 255, 255, 0) for item in data]
rgba.putdata(new_data)
rgba.save('changed.png', 'PNG')
However, if your background is of different shades, then you will have to write additional checks and determine the boundaries of acceptable shades of green.

Related

Enhance image quality by white and black clearer

I am trying to improve the quality of an image using python. How can I get white and black more clearer so as to enhance the quality of the image
Here's my try
from PIL import Image
def enhance_image(img):
black = (0, 0, 0)
white = (255, 255, 255)
threshold = (138, 138, 138)
img = Image.open(img).convert("LA")
pixels = img.getdata()
newPixels = []
for pixel in pixels:
if pixel < threshold:
newPixels.append(black)
else:
newPixels.append(white)
newImg = Image.new("RGB",img.size)
newImg.putdata(newPixels)
newImg.save("MyTemp.jpg")
Here's a sample image

PIL Image opening turns white pixels into black pixels

When I open a FULLY WHITE file with pillow (from PIL import Image) and then obtain the color of all of the pixels, you SHOULD see something like [255, 255, 255, 255, 255, 255]..... but instead i only see [0, 0, 0, 0, 0, 0]....., code is as follows:
from PIL import Image
image = Image.open("index.png", "r")
pixels = list(image.getdata())
print(pixels)
Your code doesn't convert white pixels values to black pixels. It somehow represents pixel values in different way. We can check whether it converts white pixel values to black pixels using RGB color domain. Code is shown below:
from PIL import Image
import numpy as np
img = Image.open("index.png") # open colour image
imgRgb = img.convert('RGB')
pixels = list(imgRgb.getdata())
width, height = imgRgb.size
pixels = np.asarray([pixels[i * width:(i + 1) * width] for i in range(height)], dtype=int)

Resize image in OpenCv python, filling space with color

i'm trying to resize an image to a default value, filling the entire space.
I've tried to create a blank background, pasting the image i have but i'm having errors:
# image_toresize it's the image I want to apply over the background
# the image im using for the background
blank_image = np.zeros((600,900,3), np.uint8)
blank_image = (255,255,255)
l_img = blank_image.copy()
x_offset = y_offset = 0
height, width = image_toresize.shape[:2]
l_img[0:height, 0:width] = image_toresize.copy()
this error
ValueError: could not broadcast input array from shape (90,657) into shape (90,657,3)
What can i do?
Try below code:
image_toresize = cv2.imread('flower5.jpg')
height, width = image_toresize.shape[:2]
blank_image = np.zeros((600,900,3), np.uint8)
blank_image[:,:] = (255,255,255)
l_img = blank_image.copy() # (600, 900, 3)
x_offset = y_offset = 100
# Here, y_offset+height <= blank_image.shape[0] and x_offset+width <= blank_image.shape[1]
l_img[y_offset:y_offset+height, x_offset:x_offset+width] = image_toresize.copy()
cv2.imshow('img', l_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Output:
Figure 1: Original Image
Figure 2: Above image added to a white empty background

Detect circular objects with specific color

My goal is detecting all the purple pollen in the image below and put the letter "P" in it.
But the result shows that it always mistakes a black area.
Changing the radius in circle detection would not help because I still have lots of similar images to go. So what should I do to better it?
Here is my code:
# coding: utf-8
import cv2
import numpy as np
path = "./sample.JPG"
font = cv2.FONT_HERSHEY_COMPLEX
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
# initialize the dimensions of the image to be resized and
# grab the image size
dim = None
(h, w) = image.shape[:2]
# if both the width and height are None, then return the
# original image
if width is None and height is None:
return image
# check to see if the width is None
if width is None:
# calculate the ratio of the height and construct the
# dimensions
r = height / float(h)
dim = (int(w * r), height)
# otherwise, the height is None
else:
# calculate the ratio of the width and construct the
# dimensions
r = width / float(w)
dim = (width, int(h * r))
# resize the image
resized = cv2.resize(image, dim, interpolation = inter)
# return the resized image
return resized
iml = cv2.imread(path,cv2.IMREAD_COLOR)
img = image_resize(iml,width=960)
cimg = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#cv2.GaussianBlur(cimg, (9,9),3)
cimg = cv2.medianBlur(cimg,5)
circles = cv2.HoughCircles(cimg[:,:,0],cv2.HOUGH_GRADIENT,1,cimg.shape[0]/16,param1=15,param2=20,minRadius=18,maxRadius=38)
circles = np.uint16(np.around(circles))[0,:]
for i in circles:
cv2.putText(img,'P',(i[0],i[1]), font, 0.5,(0,255,0),1,cv2.LINE_AA)
cv2.imwrite("./output.jpg",img)
In addition, I also tried using color detection since all I want to detect have the same color (purple). I follow the instructions here
but it still didn't work.
I think you can detect the purple directly in HSV color space if you can carefully choose the right hsv range. This colormap is taken from my other answers.
I select Hue(120,160), Saturation(180, 255), Value(50, 255) for this task to get the mask.
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (120, 180, 50), (160, 255, 255))
Then you can do the processing on the mask.
Links maybe helpful:
How to define a threshold value to detect only green colour objects in an image :Opencv
Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)
RGB range for color red

Recolor Image with Transparent Background

I'm trying to recolor (switch colors) in a photo with Python (preferably Python 3). I have a lot of geometrical shapes that have a thin black border, white fill, and a transparent background.
Here is an example input photo.
I would like to be able to generate a randomly colored circle.
I started with this code:
start_color = (0,0,0) # white
new_color = (255,255,255) # black
# Open image
shape_img = Image.open('circle_example.png').convert('RGB')
shape_data = np.array(shape_img)
# Replace start color with new color
shape_data[(shape_data == start_color).all(axis = -1)] = new_color
# Convert back to image
final_image = Image.fromarray(shape_data, mode='RGB')
final_image.show()
This results in:
Is there a way to replace just the white forefront and not the transparent background? (I realize that the transparent background appears white in this question, but if you look at the picture, it is transparent around the circle.)
I did find an answer. I need to import the alpha levels as well.
import numpy as np
from PIL import Image
start_color = (0, 0, 0, 255) # white
new_color = (255, 255, 255, 255) # black
# Open image
shape_img = Image.open('circle_example.png').convert('RGBA')
shape_data = np.array(shape_img)
# Replace start color with new color
shape_data[(shape_data == start_color).all(axis = -1)] = new_color
# Convert back to image
final_image = Image.fromarray(shape_data, mode='RGBA')
final_image.show()

Categories