I'm trying to align text boxes with the red dots but I have no idea where to start. Any advice/examples would be appreciated.
I used skimage and peakutils to get the locations of the ladder bands and lanes and now I would like to annotate them
%matplotlib inline
import skimage
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage import io
from skimage.color import rgb2gray
from skimage.filters import threshold_otsu
from skimage.util import invert, crop
import peakutils
from peakutils.plot import plot as pplot
import pandas as pd
from scipy.misc import toimage
from skimage import feature
def ladder_peaks(image):
image = io.imread(image)
image_grey = rgb2gray(image)
image_grey = invert(image_grey)
image_otsu = threshold_otsu(image_grey)
image_otsu = image_grey > image_otsu
xi,yi = image_otsu.shape
width_per_lane=int(xi/10)
imagecopy_otsu = np.copy(image_otsu)
imagecopy_otsu = imagecopy_otsu[:,0:(width_per_lane*2)]
ladder_mean = imagecopy_otsu.mean(1)
count = 0
x = []
for i in ladder_mean:
x.append(count)
count+=1
x = np.asarray(x)
indexes = peakutils.indexes(ladder_mean, thres=0.4, min_dist=80)
indexes = indexes.tolist()
origin = image
for i in indexes:
image[i:(i+30),0:30,:] = [255,0,0]
io.imshow(image)
Here is an implementation of how to accomplish this is in opencv. I will try to explain as much as necessary.
Import the necessary libraries.
import cv2
import numpy as np
Now open the file for opencv to read
image = cv2.imread('images/red-dots.jpg')
Keep an original copy since we will be manipulating the first image.
original_image = image
Now convert the color format from the default BGR to RGB. This step is not imperative and I encourage you to try this in the BGR color format as an exercise.
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
Now set your upper and lower limits to help us zone in on only the red hues.
min_red= np.array([210, 0, 0])
max_red = np.array([255, 33, 33])
The inRange function will allow us to ignore everything that is not between our limits.
image_red = cv2.inRange(image, min_red, max_red )
Run a canny filter; this will detection our edges.
edged = cv2.Canny(image_red, 50, 200)
Now we want to generate our contours, notice the flags. We only want simple contours.
contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
This function will find the centroids of our contours. The "magic" of cv2.moments makes this easy for us. Next it places text around the location of the contour's centroid.
def label_contour_center(image, c):
# Places some text over the contours
M = cv2.moments(c)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
cv2.putText(image, "#{}".format(i + 1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,150,250), 1)
return image
Now the enumerate function will help us keep track of how many contours we have stored. Think of i
as a count variable and c
as the variable that contains data for every individual contour.
for i,c in enumerate(contours):
orig = label_contour_center(original_image, c)
Now show the image, and destroy it upon a keyboard event.
cv2.imshow('Red dots', original_image)
cv2.waitKey(0)
cv2.destroyAllWindows()