Changing pixel color in for-loop - python

import cv
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import Image
cam = cv2.VideoCapture(0)
s,img1 = cam.read()
height, width, depth = img1.shape
print height, width
for i in range(0,height):
for j in range(0,width):
if (img1[i, j] <= [25,25,25]).all():
img1[i, j] = [255, 0, 128]
elif ((img1[i, j] > [25,25,25]).all() and (img1[i, j] <= [50,50,50]).all()):
img1[i,j] = [255, 255, 128]
elif ((img1[i, j] > [50,50,50]).all() and (img1[i, j] <= [75,75,75]).all()):
img1[i,j] = [255, 128, 0]
elif ((img1[i, j] > [75,75,75]).all() and (img1[i, j] <= [100,100,100]).all()):
img1[i,j] = [0, 255, 0]
elif ((img1[i, j] > [100,100,100]).all() and (img1[i, j] <= [125,125,125]).all()):
img1[i,j] = [68, 128, 251]
elif ((img1[i, j] > [125,125,125]).all() and (img1[i, j] <= [150,150,150]).all()):
img1[i,j] = [0, 255, 255]
elif ((img1[i, j] > [150,150,150]).all() and (img1[i, j] <= [175,175,175]).all()):
img1[i,j] = [0, 0, 255]
elif ((img1[i, j] > [175,175,175]).all() and (img1[i, j] <= [200,200,200]).all()):
img1[i,j] = [128, 128, 128]
elif ((img1[i, j] > [200,200,200]).all() and (img1[i, j] <= [225,225,225]).all()):
img1[i,j] = [0, 0, 0]
elif ((img1[i, j] > [225,225,225]).all() and (img1[i, j] <= [255,255,255]).all()):
img1[i,j] = [255, 255, 255]
else:
img1[i,j] = [0, 60, 0]
j=j+1
i=i-1
m=1
while m<2:
cv2.imshow('pseudocolor',img1)
cv2.waitKey(10)
while running this else statement works more
i.e. what should i do to give different color to pixel values such as [10, 50, 2],[23,3,167] etc
there is some problem relating the assignment of pixel values.....
not able to fetch some pixels,that is why the else statement works more number of times

import cv
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import Image
cam = cv2.VideoCapture(0)
s,img1 = cam.read()
imgg1=img1
height, width, depth = img1.shape
print height, width
for i in range(0,height):
for j in range(0,width):
if (img1[i, j] <= [25,25,25]).all():
img1[i,j] = [255, 255, 255]
imgg1[i, j] = [255, 0, 128]
elif (img1[i, j] <= [50,50,50]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [255, 255, 128]
elif (img1[i, j] <= [75,75,75]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [255, 128, 0]
elif (img1[i, j] <= [100,100,100]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [0, 255, 0]
elif (img1[i, j] <= [125,125,125]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [68, 128, 251]
elif (img1[i, j] <= [150,150,150]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [0, 255, 255]
elif (img1[i, j] <= [175,175,175]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [0, 0, 255]
elif (img1[i, j] <= [200,200,200]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [128, 128, 128]
elif (img1[i, j] <= [225,225,225]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [0, 0, 0]
elif (img1[i, j] < [255,255,255]).all():
img1[i,j] = [255, 255, 255]
imgg1[i,j] = [255, 255, 255]
else:
imgg1[i,j] = [0, 60, 0]
j=j+1
i=i-1
m=1
while m<2:
cv2.imshow('pseudocolor',imgg1)
cv2.waitKey(10)
Above program excecution seems to take about 7-8 minutes.
Is there any method to increase the excecution speed.

Related

billinear interpolation with 2d matrix image python

bilinear_interpolation(image,y,x) which takes 2d matrix image and x,y coordinates of the pixel in the image as like they are in the image
y - to the height of the image x - to the width of the image (x,y)
and returns the pixel ( from 0 to 255 ) from the calculation
notice: the x,y in the calculation aren't the same x,y that we take as parameters in the function
It can be assumed that the function receives a valid image with a single color channel
examples of the input and output:
bilinear_interpolation([[0, 64], [128, 255]], 0, 0) → 0
bilinear_interpolation([[0, 64], [128, 255]], 1, 1) → 255
bilinear_interpolation([[0, 64], [128, 255]], 0.5, 0.5) → 112
bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1.5) → 160
assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1) == 160
assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 1.5) == 160
assert bilinear_interpolation([[0, 64], [128, 255]], 0, 1) == 64
assert bilinear_interpolation([[0, 64], [128, 255]], 0, 0) == 0
assert bilinear_interpolation([[0, 64], [128, 255]], 1, 1) == 255
assert bilinear_interpolation([[0, 64], [128, 255]], 0.5, 0.5) == 112
assert bilinear_interpolation([[255, 255], [255, 255]], 0.5, 1.5) == 255
assert bilinear_interpolation([[255, 255], [255, 255]], 0, 1) == 255
assert bilinear_interpolation([[255, 255], [255, 255]], 1.5, 1.5) == 255
So what I tried is like this:
def bilinear_interpolation(image, y, x):
xa = math.floor(x)
ya = math.floor(y)
if(xa >= len(image[0]) and ya >= len(image)):
xa = len(image[0]) - 1
ya = len(image) - 1
a = image[ya][xa]
elif (xa >= len(image[0]) ):
xa = len(image[0]) - 1
a = image[ya][xa]
elif (ya >= len(image)):
ya = len(image) - 1
a = image[ya][xa]
else:
a = image[ya][xa]
if(ya + 1 >= len(image)):
b = image[ya][xa]
else:
b = image[ya + 1][xa]
if (xa + 1 >= len(image[0])):
c = image[ya][xa]
else:
c = image[ya][xa + 1]
if(xa + 1 >= len(image[0]) and ya + 1 >= len(image)):
d = image[ya][xa]
elif (xa + 1 >= len(image[0]) ):
d = image[ya + 1][xa]
elif (ya+1 >= len(image)):
d = image[ya][xa + 1]
else:
d = image[ya + 1][xa + 1]
dx = x - math.floor(x)
dy = y - math.floor(y)
interpolation_factor = a *( 1 - dx)*(1 - dy) + b * dy * (1 - dx) + c * dx * (1 - dy) + d * dx * dy
return round(interpolation_factor)
but its still failing for me.. I always get list index out of range in huge matrix like picture with size 460 x 460
any direction?

simple version of Game Of Life game doesnt behave correctly [duplicate]

This question already has answers here:
Does Python make a copy of objects on assignment?
(5 answers)
Closed 2 years ago.
Here's the full code. I've left out few unnecessary things
import random
import pygame
FPS = 1
WIDTH, HEIGHT = 400, 400
RESOLUTION = 40
GRAY = (200, 200, 200)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Game of Life")
def draw_grid(win, cols, rows):
for i in range(cols):
for j in range(rows):
x = i * RESOLUTION
y = j * RESOLUTION
pygame.draw.rect(win, GRAY, (x, y, RESOLUTION, RESOLUTION), 1)
def make_2d_array(cols, rows):
arr = []
for i in range(cols):
arr.append([])
for j in range(rows):
arr[i].append(0)
return arr
def count_neighbours(grid, x, y):
neighbourCount = 0
for i in range(-1, 2):
for j in range(-1, 2):
neighbourCount += grid[x + i][y + j]
return neighbourCount
def draw_squares(win, grid, cols, rows):
#nextA = make_2d_array(cols, rows)
nextA = grid
for i in range(len(grid)):
for j in range(len(grid[i])):
x = i * RESOLUTION
y = j * RESOLUTION
if grid[i][j] == 1:
pygame.draw.rect(win, WHITE, (x, y, RESOLUTION, RESOLUTION))
elif grid[i][j] == 0:
pygame.draw.rect(win, BLACK, (x, y, RESOLUTION, RESOLUTION))
for i in range(cols):
for j in range(rows):
if i == 0 or i == cols-1 or j == 0 or j == rows-1:
nextA[i][j] = grid[i][j]
else:
state = grid[i][j]
neighbours = count_neighbours(grid, i, j)
if state == 0 and neighbours == 3:
nextA[i][j] = 1
elif state == 1 and (neighbours < 2 or neighbours > 3):
nextA[i][j] = 0
else:
nextA[i][j] = state
grid = nextA
def main():
run = True
clock = pygame.time.Clock()
cols = int(WIDTH / RESOLUTION)
rows = int(HEIGHT / RESOLUTION)
grid = make_2d_array(cols, rows)
"""for i in range(cols):
for j in range(rows):
grid[i][j] = random.randint(0, 1)"""
#glider test
grid = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
draw_squares(WIN, grid, cols, rows)
draw_grid(WIN, cols, rows)
pygame.display.update()
pygame.quit()
main()
I was following along with a tutorial that was written in Java or JavaScript but the rules are the same and should work but they don't.
The rules simplified should be this:
if state == 0 and neighbours == 3:
nextA[i][j] = 1
elif state == 1 and (neighbours < 2 or neighbours > 3):
nextA[i][j] = 0
else:
nextA[i][j] = state
but when I run the code the first if-statement works I'm pretty sure (it's kinda hard to understand the program behaves weirdly).
The implementation of the rules is correct, but in Conway's Game of Life you have to create a new and empty grid every turn. The fields in the new grid must be determined depending on the fields in the current grid and the evolution rules.
Create a new and empty grid in draw_squares, but return the new grid form the function:
def draw_squares(win, grid, cols, rows):
# nextA = grid # <--- DELETE
nextA = make_2d_array(cols, rows) # <--- ADD
# [...]
return nextA # <-- return the new grid
Make the new grid the current grid by assigning the new grid returned by draw_squares to grid:
grid = draw_squares(WIN, grid, cols, rows)
Additionally the computation of the neighbors is wrong. A field is not a neighbor of itself:
def count_neighbours(grid, x, y):
neighbourCount = 0
for i in range(-1, 2):
for j in range(-1, 2):
if i != 0 or j != 0:
neighbourCount += grid[x + i][y + j]
return neighbourCount

Python array fill optimisation

I have a color array like this:
colors = [
[50, 0, 255], # Blue
[255, 0, 0], # Red
[255, 0, 180], # Pink
[255, 140, 0], # Orange
[255, 255, 0], # Jaune
[0, 255, 255], # Cyan
]
I have a big pixels array:
pixels = [0] * width * height * 3
I want to build an image which contains random blocks of the same color:
for y in range(block_count_y):
for x in range(block_count_x):
color = random.choice(colors)
for yp in range(block_height):
for xp in range(block_width):
offset = (y * width * block_height + yp * width + x * block_width + xp) * 3
pixels[offset + 0] = color[0]
pixels[offset + 1] = color[1]
pixels[offset + 2] = color[2]
Then i have to get bytes pixels with this:
bytes(pixels)
My loops are very slow. I am looking for a way to optimize this.
I have tried numpy and list comprehension but it does not work...
Any idea ?
Thanks

How to use numpy.where to change all pixels of an image?

I have an image of shape (300,300,3) consisting of these pixels [255, 194, 7],[224, 255, 8],[230, 230, 230],[11, 102, 255]. I want to change this pixel [230, 230, 230] to [255,255,255]. And rest other pixels to [0,0,0]. So I'm applying numpy where function to switch the pixels. Below is the code:
import numpy
im = numpy.array([[[255, 194, 7],[224, 255, 8],[230, 230, 230],[11, 102, 255]]])
im[np.where((im == [230, 230, 230]).all(axis = 2))] = [255,255,255]
im[np.where((im != [255,255,255]).all(axis = 2))] = [0,0,0]
The first code is working fine, but all the pixels that have 255 in it like [11, 102, 255] doesnot get flipped at all in the second line. and the image remains same. Can anyone tell me what I'm doing wrong ?
import numpy as np
im = np.array([[[255, 194, 7],[224, 255, 8],[230, 230, 230],[11, 102, 255]]])
Like this?
Make a mask and use it to change the values.
>>> mask = im == 230
>>> im[mask] = 255
>>> im[np.logical_not(mask)] = 0
>>> im
=> array([[[ 0, 0, 0],
[ 0, 0, 0],
[255, 255, 255],
[ 0, 0, 0]]])
Or using numpy.where
>>> np.where(im==230, 255, 0)
=> array([[[ 0, 0, 0],
[ 0, 0, 0],
[255, 255, 255],
[ 0, 0, 0]]])
try
np.array_equal(arr1, arr2)

Working on multidimensional arrays

I'm trying to scale the colors of images to predefined ranges. Based on least-squared error from palette's range of colors, a color is assigned to output pixel.
I have written the code in python loops is there a better vectorized way to do this?
import numpy as np
import skimage.io as io
palette = [
[180, 0 , 0],
[255, 150, 0],
[255, 200, 0],
[0, 128, 0]
]
IMG = io.imread('lena.jpg')[:,:,:3]
DIM = IMG.shape
IOUT = np.empty(DIM)
for x in range(DIM[0]):
for y in range(DIM[1]):
P = ((np.array(palette)-IMG[x,y,:])**2).sum(axis=1).argmin()
IOUT[x,y,:] = palette[P]
Can the loops be avoided and solved using numpy operations itself?
Don't loop over all pixels, but over all colors:
import pylab as pl
palette = pl.array([[180, 0, 0], [255, 150, 0], [255, 200, 0], [0, 128, 0]])
img = pl.imread('lena.jpg')[:, :, :3].astype('float')
R, G, B = img[:, :, 0].copy(), img[:, :, 1].copy(), img[:, :, 2].copy()
dist = pl.inf * R
for i in range(len(palette)):
new_dist = pl.square(img[:, :, 0] - palette[i, 0]) \
+ pl.square(img[:, :, 1] - palette[i, 1]) \
+ pl.square(img[:, :, 2] - palette[i, 2])
R[new_dist < dist] = palette[i, 0]
G[new_dist < dist] = palette[i, 1]
B[new_dist < dist] = palette[i, 2]
dist = pl.minimum(dist, new_dist)
pl.clf()
pl.subplot(1, 2, 1)
pl.imshow(img.astype('uint8'))
pl.subplot(1, 2, 2)
pl.imshow(pl.dstack((R, G, B)))
Edit: The loop-less alternative. ;)
import pylab as pl
palette = pl.array([[180, 0 , 0], [255, 150, 0], [255, 200, 0], [0, 128, 0]])
img = pl.imread('lena.jpg')[:, :, :3]
pl.clf()
pl.subplot(1, 2, 1)
pl.imshow(img)
IMG = img.reshape((512, 512, 3, 1))
PAL = palette.transpose().reshape((1, 1, 3, -1))
idx = pl.argmin(pl.sum((IMG - PAL)**2, axis=2), axis=2)
img = palette[idx, :]
pl.subplot(1, 2, 2)
pl.imshow(img)

Categories

Resources