-2

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.

My image


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)
Elijah
  • 23
  • 1
  • 7
  • 1
    You have listed some tags that might be relevant to your question. Do you have any code started at all? It's easier to understand where you want to go if we see your thought process through code. – Ron Norris Jun 20 '17 at 19:38
  • Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation. [on topic](http://stackoverflow.com/help/on-topic) and [how to ask](http://stackoverflow.com/help/how-to-ask) apply here. StackOverflow is not a design, coding, research, or tutorial service. – Prune Jun 20 '17 at 20:02
  • ["Can Someone Help Me?" is not a valid SO question](https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question). This usually suggests that what you need is half an hour with a local tutor or walk through a tutorial, rather than Stack Overflow. – Prune Jun 20 '17 at 20:02

1 Answers1

3

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()
avereux
  • 572
  • 1
  • 5
  • 15
  • I'm having trouble with types, to use a image it needs to be ndarray, but for cv it has to be dtype = int, otherwise I get the TypeError data = 17. The only place this is troubling me is cv2.putText(image, "#{}".format(i + 1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,150,250), 1) – Elijah Jun 22 '17 at 13:54
  • Run `image.dtype`, what type do you get? – avereux Jun 22 '17 at 14:29
  • When I ran 'np.dtype(original_image)' I got int32 – Elijah Jun 22 '17 at 14:52
  • is your image a jpeg? Your dtype needs to be`uint8`. https://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html – avereux Jun 22 '17 at 15:19
  • I'm getting ' TypeError: array is not a numpy array, neither a scalar ' for this line ' orig = label_contour_center(original_image, c) '. But original_image is type: 'numpy.ndarray' – Elijah Jun 22 '17 at 15:57
  • that's odd because the code works fine for me; did you copy the snippets exactly as they are show above? also which version of opencv are you using? – avereux Jun 22 '17 at 17:10
  • I copied all of the snippets exactly as you have them. My version of opencv is 3.2. Images are Jpeg. – Elijah Jun 22 '17 at 17:42
  • try: `cv2.putText(image, str(i+1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,150,250), 1)` in place of `cv2.putText(image, "#{}".format(i + 1), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,150,250), 1)`. Works fine on opencv 2.4.13. – avereux Jun 22 '17 at 17:58
  • Try this after reading in the image. `image = image.astype(np.uint8)` – avereux Jun 26 '17 at 13:20
  • Okay if you are still willing to provide some mild assistance, I discovered my problem. I needed 3 variables that saved (image, contours, hierarchy). Thats why I was getting the type errors the image and contour arrays were being combined. Now after taht was settled I'm getting a 'float division by zero error' on this line: cx = int(M['m10'] / M['m00']) I am trying to change my squares to not have zeros to counter this error. Thanks. – Elijah Jun 26 '17 at 14:13
  • `if cv2.contourArea(c) > 0: compute centroid` – avereux Jun 26 '17 at 15:25
  • No problem, make sure to accept my answer if you found it helpful. – avereux Jun 26 '17 at 16:00