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
Related
I've searched this question up and found multiple stack overflow posts about this but they weren't helpful. I've written code to find the white pixels in an image and then draw a circle around them, but the problem is there are multiple white pixels in an image so what happens is that the circle moves rapidly from one pixel to another because all the pixels are white. I want to find the average position of all the white pixels so that the circle stays consistent.
Here's my current code:
import cv2
import numpy as np
URL = "http://192.168.1.104:81/stream"
cap = cv2.VideoCapture(URL)
def mask():
# for masking white
sensitivity = 20
lower_white = np.array([0, 0, 255 - sensitivity])
upper_white = np.array([255, sensitivity, 255])
mask = cv2.inRange(hsv, lower_white, upper_white)
result = cv2.bitwise_and(frame, frame, mask=mask)
return result
def coord_of_white():
Y, X = np.where(np.all(frame == [255, 255, 255], axis=2))
zipped = np.column_stack((X, Y))
for points in zipped:
return cv2.circle(frame, points, 20, (0, 0, 255)) # displays circles at the coordinates of white pixels
while True:
if cap.isOpened():
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
coord_of_white()
cv2.imshow("ESP32 CAM", cv2.flip(frame, 0))
cv2.imshow("ESP32 CAM MASK", cv2.flip(mask(), 0))
if cv2.waitKey(1) == ord("q"):
break
cv2.destroyAllWindows()
cap.release()
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.
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)
I have an image with few green bars. But one of them are special because it's connected to a blue colored shape. I want to draw a bounding box using minAreaRect() around the special green bar.
I was able to draw bounding boxes using minAreaRect() around all the green bars so far. But in order to filter the green bars and take only the special one, I need to identify which box contains the blue pixels.
In order to do that, I want to check every pixel inside every box to check which one contains blue pixels. Is there any way to identify the pixel coordinates of the pixels inside a bounding box. Or is there a better approach ?
import cv2 as cv
import numpy as np
# Load the aerial image and convert to HSV colourspace
image = cv.imread("1.png")
image1 = image
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
# Define lower and uppper limits of the color blue
low_blue = np.array([94, 80, 2])
high_blue = np.array([126, 255, 255])
# Mask image to only select blues
mask1 = cv.inRange(hsv, low_blue, high_blue)
# Change image to green where we found blue
image[mask1 > 0] = (0, 130, 0)
blurred_frame = cv.GaussianBlur(image, (5, 5), 0)
hsv = cv.cvtColor(blurred_frame, cv.COLOR_BGR2HSV)
low_green = np.array([25, 52, 72])
high_green = np.array([102, 255, 255])
mask = cv.inRange(hsv, low_green, high_green)
_, contours, _ = cv.findContours(mask, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
image[mask1 > 0] = (255, 0, 0)
for contour in contours:
rect = cv.minAreaRect(contour)
box = cv.boxPoints(rect)
box = np.int0(box)
Cx = rect[0][0]
Cy = rect[0][1]
cv.drawContours(image, [box], 0, (0, 0, 255), 2)
cv.imshow("Frame", image)
cv.waitKey(0)
cv.destroyAllWindows()
Here is the input image
https://ibb.co/h9cv4DN
Here is the expected output (bounding box indicated with purple color)
https://ibb.co/8Mq6Mwt
This answer looks at all the green bars in the image. It check if the green bar also contains a blue color.
for contour in contours:
rect = cv.minAreaRect(contour)
box = cv.boxPoints(rect)
box = np.int0(box)
Cx = rect[0][0]
Cy = rect[0][1]
# Make a mask of this single green line
mask = np.zeros_like(mask1)
cv.drawContours(mask, [contour], 0, 255, cv.FILLED)
sigle_green_line = cv.bitwise_and(image, image, mask = mask)
sigle_green_line = cv.cvtColor(sigle_green_line, cv.COLOR_BGR2HSV)
# Check how much blue is in the image
blue_mask = cv.inRange(sigle_green_line, low_blue, high_blue)
print(sum(sum(blue_mask)))
# If the image is not all black (all zeros) the contour contains some blue
if sum(sum(blue_mask)) > 0: print('This contour contains some blue')
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()