2

My objective here is to replace the spot in mask_image by a color corresponding to the spot in original_image. What I did here is to find connected components and labeling them, but I can't figure out how to find the corresponding labeled spot and replace it. How can i put the n circles in n objects and fill them by the corresponding intensities? Any help would be appreciated.

For example, if spot in (2, 1) in mask image should be painted by color of corresponding spot in this image below.

mask image http://myfair.software/goethe/images/mask.jpg

mask

original image http://myfair.software/goethe/images/original.jpg original image

def thresh(img):
    ret , threshold = cv2.threshold(img,5,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    return threshold

def spot_id(img):
    seed_pt = (5, 5)
    fill_color = 0
    mask = np.zeros_like(img)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    for th in range(5, 255):
        prev_mask = mask.copy()
        mask = cv2.threshold(img, th, 255, cv2.THRESH_BINARY)[1]
        mask = cv2.floodFill(mask, None, seed_pt, fill_color)[1]

        mask = cv2.bitwise_or(mask, prev_mask)

        mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

    #here I labelled them
    n_centers, labels = cv2.connectedComponents(mask)
    label_hue = np.uint8(892*labels/np.max(labels))
    blank_ch = 255*np.ones_like(label_hue)
    labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
    labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
    labeled_img[label_hue==0] = 0

    print('There are %d bright spots in the image.'%n_centers)

    cv2.imshow("labeled_img",labeled_img)
    return mask, n_centers

image_thresh = thresh(img_greyscaled)
mask, centers = spot_id(img_greyscaled)

1 Answers1

0

There is one very simple way of accomplishing this task. First one needs to sample the value at the center of each dot in mask_image. Next, one expands this color to fill the dot in that same image.

Here is some code using PyDIP (because I know it better than OpenCV, I'm an author), I'm sure something similar can be done with OpenCV alone:

import PyDIP as dip
import cv2
import numpy as np

# Load the color image shown in the question
original_image = cv2.imread('/home/cris/tmp/BxW25.png')
# Load the mask image shown in the question
mask_image = cv2.imread('/home/cris/tmp/aqf3Z.png')[:,:,0]

# Get a single colored pixel in the middle of each spot of the mask
colors = dip.EuclideanSkeleton(mask_image > 50, 'loose ends away') * original_image

# Spread that color across the full spot
# (dilation and similar operators like this one don't work with color images,
#  so we apply the operation on each channel separately)
for t in range(colors.TensorElements()):
   colors.TensorElement(t).Copy(dip.MorphologicalReconstruction(colors.TensorElement(t), mask_image))

# Save the result
cv2.imwrite('/home/cris/tmp/so.png', np.array(colors))

output of code above

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Looks nice. But opening doesnt seem to work on color images too to enlarge the spots into same size...Size of all spots should be same. – Chinmay Athavale Feb 11 '19 at 22:10
  • @ChinmayAthavale: I had posted the wrong picture, I've fixed that now. – Cris Luengo Feb 11 '19 at 22:15
  • Also one doubt.. Is there any way by which i can label spots and access them so that i can find individual spot intensity and print them by label – Chinmay Athavale Feb 12 '19 at 06:13
  • If you're using PyDIP, you can use `dip.Label` and `dip.MeasurementTool.Measure` to get the average RGB value within each of the spots in the output image here. You could also use the output of the skeleton (the single pixel mask), find the coordinates to each set pixel (you'll get one set of coordinates for each dot), and simply read the input image at those coordinates. Simply sorting these pixel coordinates will give you a labeling. – Cris Luengo Feb 12 '19 at 06:23
  • Can u give me opencv code for this? I am unable to search similar opencv functions and cant install PyDIP coz its not on pypi – Chinmay Athavale Feb 12 '19 at 19:41
  • @ChinmayAthavale: [here](https://stackoverflow.com/questions/33095476/is-there-any-build-in-function-can-do-skeletonization-in-opencv) is an OpenCV alternative to the `dip.EuclideanSkeleton` function. For `dip.MorphologicalReconstruction` see [here](https://stackoverflow.com/questions/42151348/opencv-retaining-only-marked-blobs-in-python) or [here](https://stackoverflow.com/questions/36294025/python-equivalent-to-matlab-funciton-imfill-for-grayscale). – Cris Luengo Feb 12 '19 at 21:10