How would I use tensorflow to "add" two images? - python

I have two images (assume I know their filepaths, and can reach them). How would I "add" them together, so that the function returns an image that is essentially them next to each other, so basically image1+image2=image1image2, left to right.

Assuming you aren't restricted to TensorFlow, and that the images are the same size, as Richard said, you could use numpy concatenate function (as images are treated just like a normal matrix)
import numpy as np
stackedImg = np.concatenate((img1, img2), axis=1)
// Axis=1 for horizontal stacking and 0 for vertical
And if you want to test it out with open cv
import cv2
cv2.imwrite('output.png', stackedImg)

Related

How to blur a image in Python using Pillow

I am trying to take an image and blur it in Python using Pillow.
The only things that are imported are random and Image.
The only functions of Image I can use are open, size, load, new, close, show and save.
I know that I have to take the average RGB values of the pixels surrounding every pixel and then set that value to be the RGB value of the center pixel.
The problem is that I don't know how to get these values and look at specific edge cases where there are fewer adjacent pixels.
I am not allowed to import anything and can only use lists, loops, if statements, dictionaries, and tuples.
Take a look at this: https://en.wikipedia.org/wiki/Kernel_%28image_processing%29
Basically, you'll want to loop over the image and compute the new value for each pixel. If you can change the size of the image, then you can simply ignore the borders and therefore the edge cases. Otherwise, you'll need to apply one of the edge-handling techniques listed in the wiki page.
Good luck!!
You can use numpy.lib.stride_tricks.as_strided in order to create a window along the two spatial dimensions which can then be used to average neighboring points via mean. The following uses a (3, 3) window, i.e. only considering direct neighbors but different values are possible of course. To work on the edges, the original image first gets padded by repeating the edge values. Then the window averaging process can be repeated an arbitrary number times, depending on the desired blur factor. Here is some example code:
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
original_image = np.array(Image.open('example.jpg'))
image = np.pad(original_image, ((1,), (1,), (0,)), mode='edge')
window = np.lib.stride_tricks.as_strided(
image,
image.shape + (3, 3),
image.strides + image.strides[:2]
)[:-2, :-2]
for __ in range(10):
image[1:-1, 1:-1] = window.mean(axis=(-1, -2))
plt.title('Original')
plt.imshow(original_image)
plt.figure()
plt.title('Blurred')
plt.imshow(image[1:-1, 1:-1])
plt.show()
And here are the two image versions for comparison:
Photo by Cameron Venti on Unsplash

Python to compare colored areas of images

Assuming there are only 2 colors in an image. What's the simplest way in Python to tell an image has more (the colored areas) of these 2 colors than the other (group of similar images)?
Definition of "more": the area of total colored blocks of one picture, is bigger than the other. (please note the shape of colors might be irregular)
Thank you.
Okay, after some experimentation, I have a possible solution. You can use Pillow, a common image-loading/handling library, to convert the images to an ndarray, and then use the count_nonzero() method to get your desired results. As a fun side-effect, this works with an arbitrary amount of colors. Here's full working code that I just tried:
from PIL import Image # because for some reason, that's how you import something from Pillow
import numpy as np
im = Image.open("/path/to/image.png")
arr = np.array(im.getdata())
unique_colors, counts = np.unique(arr.reshape(-1, arr.shape[1]), axis=0, return_counts=True)
Now the unique_colors variable holds the unique colors that appear in your image, and counts holds the corresponding counts for each color in the image; that is to say, counts[i] is the number of times unique_colors[i] appears in the image for any i.
How does the unique + reshaping line work? This is borrowed from this particular answer. Basically, you flatten out your image array such that it has shape (num_pixels, num_channels), which could be 1, 3, or 4 depending on your image format (single-channel, RGB, RGBA, etc.). Now that I have a giant 2D "table" of pixels, I simply find which row values (hence axis=0) are unique, and then use the return_counts keyword to return, well, the counts.
At this point, you have extracted the unique colors and counts of those colors for a single image. To compare multiple images, you would repeat this process on multiple images, find the colors they have in common, and then you can simply compare integers to find out which image has more of a particular color.
For my particular image, the format of the channels happened to be RGBA; in any case, I would recommend printing out arr.shape prior to the reshape step to verify that you have the correct index. If you/anyone else knows of a more general method to find the channel index of an image obtained in this fashion — I'm all ears. Thus, you may have to change the index of arr.shape to something else depending on your image. For the record, I tried this on a .png image, like you specified. Hope this helps!

Select subarray from a numpy array on labels

I have processed an image with a skimage library's segmentation module. It produces a square numpy array with all segments labelled with unique number. Let's say we have a 400*400 image with let's say 500 segments labelled with 500 unique numbers.
I need to select 500 subarrays for each segment and save each as a separate image.
I could use a very brutal simple algorithm with a couple of for loops, but I strongly believe there's a simpler method using numpy masking methods. The problem is I cannot cope with it myself :-(
The code that generates the segments is very simple:
from skimage import future, graph, segmentation
import numpy as np
img_name = 'lion.jpg'
img = io.imread(img_name)
labels = segmentation.slic(img, compactness=10, n_segments=500)
As a result we have a 2D array labels.
My objective is to run a loop
for label in labels:
and cut subarrays for each label as a square with ones for pixels labelled and zeros for the remaining pixels.
Thanks,
Franek

Crop foreground of image in Python

I have manipulated a jpg image so that I have foreground isolated, and all black pixels everywhere else.
I'd like to be able to crop the image so that there are no full black rows above and below, or full black columns left and right of the foreground.
I'm thinking I could get the 4 indices I need just looping through the Numpy array, but was wondering if there is a more straightforward and/or fast approach.
import numpy as np
import matplotlib.pyplot as plt
im=np.array(
[[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,1,1,0,0,0],
[0,0,1,1,0,0,0],
[0,0,0,0,0,0,0]])
plt.imshow(im, cmap=plt.cm.gray,interpolation='nearest')
Then something happens here and I get:
im[~np.all(im == 0, axis=1)] can remove the rows with all zero. axis=2 will be the columns deletion. Would that work for you?

Flipping a image vertically, relation ship between the original picture and the new one. [python]

I am trying to flip a picture on its vertical axis, I am doing this in python, and using the Media module.
like this:
i try to find the relationship between the original and the flipped. since i can't go to negative coordinates in python, what i decided to do is use the middle of the picture as the reference.
so i split the picture in half,and this is what i am going to do:
[note i create a new blank picture and copy each (x,y) pixel to the corresponding to (-x,y), if the original pixel is after the middle.
if its before the middle, i copy the pixel (-x,y) to (x,y)
so i coded it in python, and this is the result.
Original:
i got this:
import media
pic=media.load_picture(media.choose_file())
height=media.get_height(pic)
width=media.get_width(pic)
new_pic=media.create_picture(width,height)
for pixel in pic:
x_org=media.get_x(pixel)
y_org=media.get_y(pixel)
colour=media.get_color(pixel)
new_pixel_0=media.get_pixel(new_pic,x_org+mid_width,y_org) #replace with suggested
#answer below
media.set_color( new_pixel_0,colour)
media.show(new_pic)
this is not what i wanted, but i am so confused, i try to find the relationship between the original pixel location and its transformed (x,y)->(-x,y). but i think that's wrong. If anyone could help me with this method it would be great full.
at the end of the day i want a picture like this:
http://www.misterteacher.com/alphabetgeometry/transformations.html#Flip
Why not just use Python Imaging Library? Flipping an image horizontally is a one-liner, and much faster to boot.
from PIL import Image
img = Image.open("AFLAC.jpg").transpose(Image.FLIP_LEFT_RIGHT)
Your arithmetic is incorrect. Try this instead...
new_pixel_0 = media.get_pixel(new_pic, width - x_org, y_org)
There is no need to treat the two halves of the image separately.
This is essentially negating the x-co-ordinate, as your first diagram illustrates, but then slides (or translates) the flipped image by width pixels to the right to put it back in the range (0 - width).
Here is a simple function to flip an image using scipy and numpy:
import numpy as np
from scipy.misc import imread, imshow
import matplotlib.pyplot as plt
def flip_image(file_name):
img = imread(file_name)
flipped_img = np.ndarray((img.shape), dtype='uint8')
flipped_img[:,:,0] = np.fliplr(img[:,:,0])
flipped_img[:,:,1] = np.fliplr(img[:,:,1])
flipped_img[:,:,2] = np.fliplr(img[:,:,2])
plt.imshow(flipped_img)
return flipped_img

Categories

Resources