Iterating over jit.matrix

Mar 20, 2012 at 7:48pm

Iterating over jit.matrix

Hello

What I’m trying to do is very simple. It takes three lines in matlab. But I can’t figure out how to do it in max.

I have a jit.matrix that holds a black and white picture. What I want to do is run over the rows of the matrix, from right to left, and when I hit a non-white cell, add the column coordinate of that cell to a list.

(The picture is a profile of a face, where the face is black and background white, and I’m trying to find the outline of the face).

How can I do this?

#62505
Mar 20, 2012 at 11:47pm

[jit.iter] ?

Or the brute-force way, using [uzi] and the “getcell” message, holding the cell coordinates, and if the value is 0, bang the coordinates into your list. This “nested for-loop-approach” will be a lot slower than [jit.iter] though.

#225780
Mar 21, 2012 at 5:08pm

How exactly would you do it with iter? I need to jump to the next line every time I encounter a black pixel.

#225781
Mar 21, 2012 at 9:13pm

You’d probably need to use the getcell approach if you have to conditionally jump to the next line.

Another idea is [jit.spill] and you can find the first black (0) element by using [zl filter 0] on the list. This will give you all the black pixels in the row and their indices, so you can keep additional ones if you want. [jit.spill] will be a lot faster than getcell too.

#225782
Mar 21, 2012 at 10:02pm

There’s no good solution for doing this kind of thing with standard Jitter objects. I wrote an object years ago to solve this exact problem. It’s called xray.jit.cellcoords. You can download the objects here:

http://www.mat.ucsb.edu/~whsmith/xray.html

#225783
Mar 22, 2012 at 7:50pm

Thanks! This looks really helpful. I’m having trouble understanding the xray.jit.cellcoords help file, though. What exactly does this object do?

#225784
Mar 23, 2012 at 8:17am

It gives you the cell coordinates of all cells of the input matrix that are logic 1 (1 or 255 if it’s char). For example a 1-plane float32 matrix that looks like

[0 1 0]
[1 0 0]
[0 0 1]

outputs a matrix:

[(1, 0), (0, 1), (2, 2)]

#225785
Mar 23, 2012 at 9:58am

Okay, so it outputs a matrix of tuples? Or is it a two plane matrix?

I’m not sure I see how I could use such a matrix to find just the first white cell in each row…

#225786
Mar 23, 2012 at 10:33am

Maybe the cellminmaxx object would be better? Can it be used to scan the matrix horizontally and find the first nonzero cell value in each row?

#225787
Mar 23, 2012 at 10:49am

Hi mrosenschein,

If the resolution of the image is not too big I would do that by converting the matrix into a list using jit.spill. Then you have plenty of ways to get the indices corresponding to non-white cells, using the functions from the zl family, that also works for long lists, i.e. big images. But if the image has many pixels, using an external is the way to go.

Alexis

#225788
Mar 23, 2012 at 11:16am

I think you could simply use [jit.iter] and [togedge] to detect zero/non-zero transitions.

#225789
Mar 23, 2012 at 5:31pm

Another useful object if you’re trying to get a silhouette is xray.jit.distance. You can pass in a binary mask to it and then threshold the result to get just the outline pixels. If you then piped that into xray.jit.cellcoords, you’d have a matrix with all of the outline pixel cell coordinates.

#225790
Mar 23, 2012 at 7:21pm

That’s exactly what I need! Sorry for the n00bness but what exactly do you mean by “pass in a binary mask and then threshold the result”? Thanks for the help!

#225791
Mar 23, 2012 at 7:27pm

This patch that you (Wesley) posted in this thread http://www.cycling74.com/forums/topic.php?id=547 looks very similar to what I’m trying to do. I just need to take it one more step and get a vector with the cell coordinates of the outline pixels. If you could explain how to do that using xray.jit.distance I would be over the moon :)

Attachments:
  1. silhouette.maxpat
#225792
Mar 23, 2012 at 7:45pm

Here’s a picture as an example of what I’m going for. With Wesley’s patch I can turn the girl’s face into black and white outline. But I need to get rid of the white pixels inside the face (the eyes, for example), if I’m going to use jit.cellcoords to extract just the pixels that make up the silhouette.

Attachments:
  1. Screenshot20120323at9.43.05PM.png
#225793
Mar 23, 2012 at 11:52pm

Here’s what I was thinking:

– Pasted Max Patch, click to expand. –

You’ll probably need to use some cv.jit objects to fill in the area you want silhouetted. The basic idea is to color everything you want inside the shape white. You can then use jit.robcross or whatever to create the outline.

#225794
Mar 24, 2012 at 12:10am

it would be great to be able to do the equivalent of [zl sub] with an object similar to jit.spill – gets all coordinates that are x in a normal max list, unlike jit.xray.cellcoord.

for my money [zl sub] is a great way to detect positions, and being able to apply this directly would be handy while reducing the number of big non-jitter lists flying around.

#225795
Mar 24, 2012 at 10:16am

Hi Wesley,

I’m sorry to be so slow but I’m not sure I understand what the patch you posted does. I’m seeing three outputs: one that looks like edge detection of the image, one in grayscale and then the third is just black.

If I understand correctly what you’re suggesting is to somehow fill in the face so that it will be all white and the use detection to extract just the silhouette line. That sounds great but I have no experience at all with the cv.jit objects…are there any in particular that could help me do that?

Thanks so much

#225796

You must be logged in to reply to this topic.