Python Otsu Threshold of a 2-dimensional array - python

I wrote an Ant Colony Optimalization code in Python for finding edges in an image.
I based it off a document : http://ohm.ecce.admu.edu.ph/wiki/pub/Main/TotoOppus/ant_colony_optimization_for_image_edge_detection_WSEASConference.pdf
In the end i have a pheromone matrix size [I,J] (numpy array) where I,J are equal to Width and Height of the given picture that i find edges in.
Now i want to find the Otsu Threshold of that matrix and put white pixels onto black canvas of [I,J] size, in the places where the corresponding pheromones values are bigger then the threshold. Is there a function to easily find Otsu threshold of a numpy 2 dimensional array ?

This function from scikit-image should work to derive the Otsu threshold for your array, as the image input is an ndarray.

Related

how can i make mask image bigger with python numpy?

I have array that represent a mask with shape (3080, 2000) and dtype('uint8'),
the following picture
[mask image ][1]
my mask is not always a rectangle could be any shape, I just want to make the mask bigger, I mean to extend it a few pixels in every direction how can I achieve that.
[1]: https://i.stack.imgur.com/K2zaA.png

Detecting lines in an image using OpenCV with Python

[Updated The Question at the End]
I'm trying to detect a design pattern of simple geometrical shapes in a 640x480 image. I have divided the image in 32x32 blocks and checking in which block each shape's center lies.
Based on this calculation I created a numpy matrix of (160x120) zeros (float32) with
col=640/4
row=480/4
Each time a shape is found, the center is calculated and check in which block it is found. The corresponding item along with its 8 neighbors in 160x120 numpy array are set to 1. In the end the 160x120 numpy array is represented as a grayscale image with black background and white pixels representing the blocks of detected shapes.
As shown in the image below.
The image in top left corner represents the 160x120 numpy array. No issue so far.
As you can see the newly generated image has a white line on black foreground. I want to find the rho,theta,x0,y0,x1,y1 for this line. So I decided to use HoughLines transformation for this.
For is as followed:
edges = cv2.Canny(np.uint8(g_quadrants), 50, 150, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
print lines
Here g_quadrants is the 160x120 matrix representing a gray scale image but output of cv2.HoughLines does not contain anything but None.
Please help me with this.
Update:
The small window with a black and white (np.float32 consider GrayScale) image displaying a white is what I get actually when I
Divide the 640x480 in 32x32 blocks
Find the triangles in the image
Create a 32x32 matrix to map the results for each block
Update the corresponding matrix element by 1 if a triangle is found in a block
Zoomed View:
You can see there are white pixels forming a straight line. The may be some unwanted detected. I need to eliminate unwanted lone pixels and reconstructing a continuous straight line. That may be achieved by dilating then eroding the image. I need the find x0,y0, x1,y1, rho, theta of this line.
Their may be more than one lines. In that case I need to find top 2 lines with respect to length.

How to get border pixels of an image in python?

I have an image, using steganography I want to save the data in border pixels only.
In other words, I want to save data only in the least significant bits(LSB) of border pixels of an image.
Is there any way to get border pixels to store data( max 15 characters text) in the border pixels?
Plz, help me out...
OBTAINING BORDER PIXELS:
Masking operations are one of many ways to obtain the border pixels of an image. The code would be as follows:
a= cv2.imread('cal1.jpg')
bw = 20 //width of border required
mask = np.ones(a.shape[:2], dtype = "uint8")
cv2.rectangle(mask, (bw,bw),(a.shape[1]-bw,a.shape[0]-bw), 0, -1)
output = cv2.bitwise_and(a, a, mask = mask)
cv2.imshow('out', output)
cv2.waitKey(5000)
After I get an array of ones with the same dimension as the input image, I use cv2.rectangle function to draw a rectangle of zeros. The first argument is the image you want to draw on, second argument is start (x,y) point and the third argument is the end (x,y) point. Fourth argument is the color and '-1' represents the thickness of rectangle drawn (-1 fills the rectangle). You can find the documentation for the function here.
Now that we have our mask, you can use 'cv2.bitwise_and' (documentation) function to perform AND operation on the pixels. Basically what happens is, the pixels that are AND with '1' pixels in the mask, retain their pixel values. Pixels that are AND with '0' pixels in the mask are made 0. This way you will have the output as follows:
.
The input image was :
You have the border pixels now!
Using LSB planes to store your info is not a good idea. It makes sense when you think about it. A simple lossy compression would affect most of your hidden data. Saving your image as JPEG would result in loss of info or severe affected info. If you want to still try LSB, look into bit-plane slicing. Through bit-plane slicing, you basically obtain bit planes (from MSB to LSB) of the image. (image from researchgate.net)
I have done it in Matlab and not quite sure about doing it in python. In Matlab,
the function, 'bitget(image, 1)', returns the LSB of the image. I found a question on bit-plane slicing using python here. Though unanswered, you might want to look into the posted code.
To access border pixel and enter data into it.
A shape of an image is accessed by t= img.shape. It returns a tuple of the number of rows, columns, and channels.A component is RGB which 1,2,3 respectively.int(r[0]) is variable in which a value is stored.
import cv2
img = cv2.imread('xyz.png')
t = img.shape
print(t)
component = 2
img.itemset((0,0,component),int(r[0]))
img.itemset((0,t[1]-1,component),int(r[1]))
img.itemset((t[0]-1,0,component),int(r[2]))
img.itemset((t[0]-1,t[1]-1,component),int(r[3]))
print(img.item(0,0,component))
print(img.item(0,t[1]-1,component))
print(img.item(t[0]-1,0,component))
print(img.item(t[0]-1,t[1]-1,component))
cv2.imwrite('output.png',img)

Using OpenCV Python, How would you make all black pixels transparent, and then overlay it over original image

I'm trying to make a colored mask, white.
And my idea is to:
make black pixels transparent in the mask
merge the two images
crop images
so then my original masked area will be white.
What kind of OpenCV python code/methods would I need?
Like so:
Original
Mask
Desired result (mocked up - no green edges)
Instead of
I suppose to do a color threshold to get the mask itself.
The result I got in a first quick and dirty attempt with Hue 43-81, Saturation 39-197 and Brightness from 115-255 is:
The next step is a whole fill algorithm to fill the inside of the mask. Note that also one small area to the right is selected.
The next step is a substraction of the two results (mask-filled_mask):
Again fill the wholes and get rid of the noisy pixels with binary opening:
Last mask the image with the created mask.
Every step can be adjusted to yield optimal results. A good idea is to try the steps out (for example with imageJ) to get your workflow set up and then script the steps in python/openCV.
Refer also to http://fiji.sc/Segmentation.
I am assuming your mask is a boolean numpy array and your 2 images are numpy arrays image1 and image2.
Then you can use the boolean array as multiplier.
overlay= mask*image1 + (-mask)*image2
So you get the "True" pixels from image1 and the False pixels from image2

numpy and detecting .mean() in a radius

I'm pretty new to numpy.
I have been looking around how to do this but I can't find anything easy enough.
This is the problem.
I'm identifying particles in red (it's ok and done) so I have an array with locations.
I make a new image with these locations with grey dilation and scipy.ndimage, having the dilated positions with a value and the rest 0.
Then I multiply this image with another image (green color), so that the new color only has signals where you have particles in red. What I want to do is to detect the mean of intensities in this other color per given point, in a given radius or square for example.
How can I do this? Do I make scipy.ndimage.measurements.label in the initial color and then use the same array indexes to have the means? Or I can just have x,y coordinates and do the mean() over a given radius?

Categories