2

Trying to extract the pixels outside and inside the edges within it's own area, currently i am applying the scipy Sobel filter like this:

im = scipy.misc.imread(filename)
im = im.astype('int32')
dx = ndimage.sobel(im, axis=0)
dy = ndimage.sobel(im, axis=1)

mag = np.hypot(dx, dy)  
mag *= 255.0 / np.max(mag)

scipy.misc.imsave('sobel.jpg', mag)

Currently the results are:

enter image description here enter image description here

The idea is to get the pixels outside the edge detection, for example these areas:

enter image description here

How can i extract an array of the area outside and inside the sobel filter?

Wahtever
  • 3,597
  • 10
  • 44
  • 79
  • 1
    You would have to define what is *outside* and what is *inside*. Visually it might seem pretty simple, as you know what you want to extract (a person), but an image is an array of numbers for a computer, and it doesn't know about higher level connectivity. So, for that specific example, you could go row by row and mask pixels from left and right until you pick a *peak* in the sobel gradient. However, if you want a general method, it is not as simple as you might think, and it is not going to be as simple as doing some *magic* to the sobel filter. It is an example of https://xkcd.com/1425/ – Imanol Luengo Dec 15 '16 at 14:51
  • If your images are simple and easy, try something with contours in [opencv](http://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html) or [scikit-image](http://scikit-image.org/docs/dev/auto_examples/plot_contours.html) – Imanol Luengo Dec 15 '16 at 14:54
  • You are trying to solve an image "segmentation" problem, which is in general a very difficult problem and has been a very active area of research for many years. However, since the background in your image is very simple (just a white wall), maybe some simple method would work. It might be easiest just to find some good image segmentation code online. – littleO Dec 15 '16 at 21:47
  • What do you need this for? Would it be acceptable to manually label some of the foreground and background pixels? – littleO Dec 16 '16 at 01:32
  • @ImanolLuengo - Unfortunately with image contours it's unable to do a semi accurate presentation of the image. – Wahtever Dec 16 '16 at 05:47
  • @littleO I am currently open to any method, whether automatic or label foreground and background pixels. But the labeling would be rough i think, not as exact. Can you give me an idea of how i would go about that ? – Wahtever Dec 16 '16 at 05:48

1 Answers1

2

Here's an approach using interactive image segmentation. In this approach, you must manually label some of the foreground pixels and some of the background pixels, like this:

Labeled image

(I did the labeling in MS Paint.) The code below uses the function skimage.segmentation.random_walker to do the image segmentation, and produces this segmented image:

enter image description here

(This approach can also handle images with much more complicated background regions.) Here's the code:

import skimage
import skimage.viewer
import skimage.segmentation
import skimage.data
import skimage.io
import matplotlib.pyplot as plt
import numpy as np

img = skimage.io.imread("D:/Users/Pictures/img.jpg")
imgLabeled = skimage.io.imread("D:/Users/Pictures/imgLabeled.jpg")

redChannel = imgLabeled[:,:,0]
greenChannel = imgLabeled[:,:,1]
blueChannel = imgLabeled[:,:,2]
markers = np.zeros(img.shape,dtype=np.uint)
markers[(redChannel < 20) & (greenChannel > 210) & (blueChannel < 20)] = 1
markers[(redChannel < 20) & (greenChannel < 20) & (blueChannel > 210)] = 2
plt.imshow(markers)

labels = skimage.segmentation.random_walker(img, markers, beta=1000, mode='cg')

seg1 = np.copy(img)
seg1[labels==2] = 0
seg2 = np.copy(img)
seg2[labels==1] = 0

# plt.imsave("D:/Users/Pictures/imgSeg.png",seg1)

plt.figure()
plt.imshow(seg1)
plt.figure()
plt.imshow(seg2)
littleO
  • 942
  • 1
  • 11
  • 26