4

I have a binary image of large size (2000x2000). In this image most of the pixel values are zero and some of them are 1. I need to get only 100 randomly chosen pixel coordinates with value 1 from image. I am beginner in python, so please answer.

2
  • Great. What have you tried? PIL --> Python Imaging Library module might help you. Commented Jul 1, 2017 at 6:32
  • Also can you post the image? Commented Jul 1, 2017 at 6:32

4 Answers 4

3

I'd suggest making a list of coordinates of all non-zero pixels (by checking all pixels in the image), then using random.shuffle on the list and taking the first 100 elements.

Sign up to request clarification or add additional context in comments.

4 Comments

just a quick question - will he need to be careful about 2080 limit as mentioned here?: docs.python.org/3/library/random.html#random.shuffle
A valid question. I guess it is up to OP to decide, because we don't know what "most" in the question means - 90%? 99%? 99.99%? If there are just a few hundred non-zero pixels, it should be safe to use random.shuffle, otherwise it might be better to use random.choice.
Awesome..! Thankyou sir. I found that random.choice can not be used here as coordinates are 2 dimensional. so i have tried random.shuffle as- coordinates = np.argwhere(img) print(coordinates.shape) index = random.shuffle(coordinates) print(index[0:100]) it gives me following error-TypeError: 'NoneType' object is not subscriptable
coordinates = np.argwhere(img) print(coordinates.shape) random.shuffle(coordinates) print(coordinates[0:100])
1

After importing necessary libraries like

import cv2
import numpy as np  
import pandas as pd  
import matplotlib.pyplot as plt 

gray_img = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE) # grayscale

gray_img[i,j] will give pixel value at (i,j) position

Try to send all these values into a file in this format

i_positition,j_position,value_of_pixel

path = os.getcwd() + '/filename.txt'  
data = pd.read_csv(path, header=None, names=['i', 'j', 'value'])

positive = data[data['value'].isin([1])]  
negative = data[data['value'].isin([0])]

positive data frame contains all the pixel positions whose value is 1.

positive['i'] ,positive['j'] will give you list of (i,j) values of all the pixels whose value is 1.

i_val=np.asarray(positive['i'])

j_val=np.asarray(positive['j'])

Now you can randomly select any value from i_val & j_val arrays.

Note: Make sure that your pixel values will be 1 or 0. If your values are 0 and 255 then change this command

positive = data[data['value'].isin([255])] 

1 Comment

Thank you..! It leads to lot of calculation. i tried np.argwhere(img) to get coordinates and random.shuffle() to get random coordinates but i got TypeError: 'NoneType' object is not subscriptable in sampling only 100 random coordinates.
0

Use below code:

import numpy as np
y_idx, x_idx = np.where(image==1)   #list of all the indices with pixel value 1

for i in range(0,100):
    rand_idx = np.random.choice(x_idx)   #randomly choose any element in the x_idx list
    x = x_idx[rand_idx]
    y = y_idx[rand_idx]
    #--further code with x,y-- 

Comments

0

here is another answer that might save some memory storage, or at least a for loop..

import numpy as np
random_image = np.random.uniform(0, 1, size=(2000, 2000)) > 0.5

sel_index = np.random.choice(np.argwhere(random_image.ravel()).ravel(), size=100)
random_x, random_y = np.unravel_index(sel_index, random_bin.shape)

I just like the usage of unravel :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.