Iterate with for loop through binarized image possible? - python

this is my python code:
import cv2
img = cv2.imread("foo.jpg")
#here I can iterate trough each pixel since I have a 2D array
for x in range(img.shape[0]):
for y in range(img.shape[1]):
pass #maipulate each pixel
gary = cv2.cvtColor(img, COLOR_BGR2GRAY)
bin = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
#here I can not iterate trough each pixel since I have a 1D array
for x in range(img.shape[0]):
for y in range(img.shape[1]):
pass
My Question:
How can I iterate through each pixel of the binary image?
I want to use a sliding window search algorithm.

Your code doesn't work because threshold() returns a tuple of 2 values: the threshold value you set (127) and a binary image. If you seperate these you can use the same double loop to access each value / pixel.
I've modified your code, as there where also a couple of typo's.
import cv2
img = cv2.imread("foo.jpg")
#here I can iterate trough each pixel since I have a 2D array
for x in range(img.shape[0]):
for y in range(img.shape[1]):
pass #maipulate each pixel
gray= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh, bin_img = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
for x in range(bin_img.shape[0]):
for y in range(bin_img.shape[1]):
pass

Related

Conditionnally assign pixel values of one image to another

I have two images ( of the same size): A and B
A is the mask, it contains regions that have zero value and others that have RGB values.
B is the RGB image that i want to change the values of some of its pixels to their correspondent A's pixels (pixels that have the same position and that are different from zero).
I think it would be something like this:
if A(i,j) <>0 then B(i,j)=A(i,j)
except that i don't know how to write it in python...
can anyone help?
If you read the images with opencv:
h = b.shape[0]
w = b.shape[1]
for y in range(0, h):
for x in range(0, w):
if a[y,x] > 0:
b[y,x] = a[y,x]
Or better, as points #Dan MaĊĦek in the comment
import numpy as np
def apply_mask(img, mask):
img = np.where(mask > 0, mask, img)
return img
Notice that in numpy arrays, the height comes first in shape. Opencv loads the image into numpy arrays.
To apply the mask for src, you can use cv2.bitwise_and:
cv2.bitwise_and(src, src, mask=mask)

Get all pixels different from a color and paint them in other image

I have image A with dimension (512, 512, 3).
I want to find all the pixels which != [255,255,255].
Given that pixels, I want to color these coordinates in another image B.
What am I doing wrong?
indices = np.where(imgA!= [255,255,255])
imgB[indices] = [0,0,0]
This template should get you on the right path:
from PIL import image
picture = Image.open(path_to_picture)
width, height = picture.size
for x in range(width):
for y in range(height):
current_color = picture.getpixel( (x,y) )
if current_color[0:3]!=(255,255,255):
picture.putpixel( (x,y), (***, ***,***) + (current_color[-1],))
picture.save(path_to_new_picture)
Note here that getpixel() will return a tuple that contains the RGBA values for the given pixel. In this example, I am assuming that you are retaining the alpha value and simply modifying the RGB values of the current pixel.
you need to loop over each pixel in the image.
... imgA!= [255,255,255] will always return true, because you are comparing a (512,512,3) nd.array to a (3,) nd.array
Even if your images are not built from numpy matricies, this point still applies. If you run into performance issues, use cython for faster for loops.

Python -- change the RGB values of the image and save as a image

I can read every pixel' RGB of the image already, but I don't know how to change the values of RGB to a half and save as a image.Thank you in advance.
from PIL import *
def half_pixel(jpg):
im=Image.open(jpg)
img=im.load()
print(im.size)
[xs,ys]=im.size #width*height
# Examine every pixel in im
for x in range(0,xs):
for y in range(0,ys):
#get the RGB color of the pixel
[r,g,b]=img[x,y]
get the RGB color of the pixel
[r,g,b]=img.getpixel((x, y))
update new rgb value
r = r + rtint
g = g + gtint
b = b + btint
value = (r,g,b)
assign new rgb value back to pixel
img.putpixel((x, y), value)
You can do everything you are wanting to do within PIL.
If you are wanting to reduce the value of every pixel by half, you can do something like:
import PIL
im = PIL.Image.open('input_filename.jpg')
im.point(lambda x: x * .5)
im.save('output_filename.jpg')
You can see more info about point operations here: https://pillow.readthedocs.io/en/latest/handbook/tutorial.html#point-operations
Additionally, you can do arbitrary pixel manipulation as:
im[row, col] = (r, g, b)
There are many ways to do this with Pillow. You can use Image.point, for example.
# Function to map over each channel (r, g, b) on each pixel in the image
def change_to_a_half(val):
return val // 2
im = Image.open('./imagefile.jpg')
im.point(change_to_a_half)
The function is actually only called 256 times (assuming 8-bits color depth), and the resulting map is then applied to the pixels. This is much faster than running a nested loop in python.
If you have Numpy and Matplotlib installed, one solution would be to convert your image to a numpy array and then e.g. save the image with matplotlib.
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
img = Image.open(jpg)
arr = np.array(img)
arr = arr/2 # divide each pixel in each channel by two
plt.imsave('output.png', arr.astype(np.uint8))
Be aware that you need to have a version of PIL >= 1.1.6

Divide the image into 4x4 blocks and save each coordinate in variable

I have an grayscale Image of 128x128 that I want to divide into 4x4 pixel non-overlapping blocks and I want to save coordinate of each pixel as variable like this-
pixel1=x,y
pixel2=x,y
pixel3=x,y
pixel4=x,y..and so on to
......
......
......
pixel16384=x,y
I know I can do it manually by defining variables, but I can use any for loop for making it faster?
After that, I'll find mean of each block by-
Average_of_block1=pixel1.mean(),pixel2.mean(),pixel3.mean(),pixel4.mean()....pixel16.mean()
Any help?Suggestions?
To get the value of the pixel you could use PIL and
you could use a for loop and append a tuple of the x and y coordinate like this:
from PIL import Image
pixels = []
i = Image.open("image.jpg")
p = i.load()
for x in range(128):
for y in range(128):
pixels.append(p[x,y]) #gets the RGB value
this would work for the whole image for those blocks you could just add an extra loop
from PIL import Image
pixels = []
i = Image.open("image.jpg")
p = i.load()
for b in range(4):
block = []
for x in range(32):
for y in range(32):
block.append(p[x,y])
#do something with pixels from block
edit:
If you want to use a grayscale image you should do this:
from PIL import Image
pixels = []
i = Image.open("image.jpg").convert("LA")
p = i.load()
for b in range(4):
block = []
for x in range(32):
for y in range(32):
block.append(p[x,y][0])
#do something with the pixels from the block
the first int in the tuple is the grayscale 0 (black) to 255 (white) the second int is the alpha but my guess would be that you don't use alpha in a grayscale image

How do I display an image from an array in python

I am trying to use PIL to display an image from an array. The array is a long list of elements which are pixel values of an image. How do I display these pixel values as an image ?
You don't specify what kind of data is in your list, so I assume it is an array with 25 elements (grouped in 5 groups of 5), which will be converted to a 5 by 5 black & white image.
from PIL import Image
import random
data = [
[1,0,0,1,0],
[1,1,1,0,0],
[1,1,0,1,0],
[1,0,1,1,0],
[0,1,1,0,1],
]
img = Image.new("1", (5, 5))
pixels = img.load()
for i in range(img.size[0]):
for j in range(img.size[1]):
pixels[i, j] = data[i][j]
img.show()
img.save("img.png")
This is similar to this question: How can I write a binary array as an image in Python?

Categories