Reputation: 165
I'm new in image processing in python, and I'm trying to do masks for cell image segmentation based on an image. I did threshold to make the image into a binary mask but what I need is center images of random size into a mask of 36x36 and I've got images above and smaller this size. The images are like this one. What I'm trying to do is to center in a zero matrix of 36x36 but I'm not used to doing image manipulation.
the original one is this:
Upvotes: 0
Views: 1260
Reputation: 53089
Here is one way using numpy 2D indexing to insert one image into another.
Load the cell image as grayscale
Create a black image into which to recenter the cell data
Threshold the cell image using Otsu thresholding
Get the contour(s) for the thresholded cell image
From each contour (presumably only one) get its bounding box and cut out the corresponding area of the gray image as roi
Compute the top left corner x and y offsets for centering the roi into the black image
Use numpy 2D array indexing to put the roi into the black image properly centered
Input:
import cv2
import numpy as np
# load image as grayscale
cell = cv2.imread('cell.png', cv2.IMREAD_GRAYSCALE)
# create 400x400 black image (larger than img) into which to do the recentering
result = np.zeros((400,400), dtype=np.uint8)
# threshold input image with Otsu thresholding
ret, thresh = cv2.threshold(cell, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('THRESH', thresh)
# get contours --- presumably just one
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
print(x,y,w,h)
roi=cell[y:y+h, x:x+w]
# compute top left corner location to center roi in result image
xoff = int((400 - w)/2)
yoff = int((400 - h)/2)
result[yoff:yoff+h, xoff:xoff+w] = roi
# display result for each bounding box from contours
cv2.imshow('CENTERED', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save resulting centered image
cv2.imwrite('cell_centered.png', result)
Upvotes: 3
Reputation: 375
Hello try this code and I make an image for you understand :)
image = [[0, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 1, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 0]]
image_width = 5
image_height = 5
lowest_x = -1
lowest_y = -1
bigest_x = -1
bigest_y = -1
# Get the square of the shape of your image (edge coordinate)
for y in range(len(image)):
for x in range(len(image[y])):
if image[y][x] != 0:
if x < lowest_x or lowest_x == -1:
lowest_x = x
if y < lowest_y or lowest_y == -1:
lowest_y = y
if x > bigest_x or bigest_x == -1:
bigest_x = x
if y > bigest_y or bigest_y == -1:
bigest_y = y
print ("Edge coordinate = " + str(lowest_y) + ":" + str(lowest_x) + " - " + str(bigest_y) + ":" + str(bigest_x))
chunk_width = bigest_x - lowest_x + 1
chunk_height = bigest_y - lowest_y + 1
print ("Chunk size = " + str(chunk_height) + " " + str(chunk_width))
y_delimiter = (image_height - chunk_height) / 2
x_delimiter = (image_width - chunk_width) / 2
print ("Start of new coord = " + str(y_delimiter) + " " + str(x_delimiter))
new_image = [[0 for i in range(image_height)] for j in range(image_width)]
for y in range(chunk_height):
for x in range(chunk_width):
new_image[y_delimiter + y][x + x_delimiter] = image[lowest_y + y][lowest_x + x]
print("")
for y in range(len(new_image)):
print ' '.join(str(x) for x in new_image[y])
Upvotes: 2