boris-kz / CogAlg

This project is a Computer Vision implementation of general hierarchical pattern discovery principles introduced in README
http://www.cognitivealgorithm.info
MIT License
90 stars 42 forks source link

Why mask is inverted in comp_range and hypot_g? #24

Closed Twenkid closed 3 years ago

Twenkid commented 5 years ago

The blob's mask is marking the coordinates of the included pixels?

dert__ = frame[-1][y0:yn, x0:xn, :]
        map = np.zeros((height, width), dtype=bool)
        for seg in e_:
            for P in seg[2]:
                for y, x, i, dy, dx, g in P[2]:
                    map[y, x] = True
        map = map[y0:yn, x0:xn]

The def comp_range(blob): # compare rng-distant pixels within blob: a component of intra_blob is about the pixels within the blob.

What's the purpose of the map's negation?

 p__ = ma.array(blob.dert__[:, :, 0], mask=~blob.map)  # apply mask = ~map
    dy__ = ma.array(blob.dert__[:, :, 1], mask=~blob.map)
    dx__ = ma.array(blob.dert__[:, :, 2], mask=~blob.map)

Is it in order to compare with adjacent border-line pixels (within higher rng)? Probably I am missing something in the picture, but it's stated "within the blob", however wouldn't that inversion cause skipping for the pixels/patterns within the blob due to the masked array, now the items would be False?

I see the negation is done also in intra_blob.hypot_g

Could you explain its purpose as well?

Thanks!

@boris-kz @khanh93vn

def hypot_g(blob):  # redefine master blob by reduced g and increased ave * 2: variable costs of comp_angle

  mask = ~blob.map[:, :, np.newaxis].repeat(4, axis=2)  # stack map 4 times to fit the shape of dert__: (width, height, number of params)

https://github.com/boris-kz/CogAlg/blob/d2974597577b4db27510db2accd28fc6314f4c49/frame_2D_alg/comp_range.py#L11

boris-kz commented 5 years ago

I recall that this is to exclude pixels that were already processed on previous stages of intra_blob. So that only additional blob-marginal pixels will be processed for comp_angle, and incremental-distance pixels for comp_range (excluding already compared lesser-distance pixels. Sorry for sloppy comments. Khanh?

On Thu, Mar 21, 2019 at 4:10 PM Todor Arnaudov notifications@github.com wrote:

The blob's mask is marking the coordinates of the included pixels?

dert_ = frame[-1][y0:yn, x0:xn, :] map = np.zeros((height, width), dtype=bool) for seg in e: for P in seg[2]: for y, x, i, dy, dx, g in P[2]: map[y, x] = True map = map[y0:yn, x0:xn]

The def comp_range(blob): # compare rng-distant pixels within blob: a component of intra_blob is about the pixels within the blob.

What's the purpose of the map's negation?

p = ma.array(blob.dert[:, :, 0], mask=~blob.map) # apply mask = ~map dy = ma.array(blob.dert[:, :, 1], mask=~blob.map) dx = ma.array(blob.dert[:, :, 2], mask=~blob.map)

Is it in order to compare with adjacent border-line pixels (within higher rng)? Probably I am missing something in the picture, but it's stated "within the blob", however wouldn't that inversion cause skipping for the pixels/patterns within the blob due to the masked array, now the items would be False?

I see the negation is done also in intra_blob.hypot_g

Could you explain its purpose as well?

Thanks!

@boris-kz https://github.com/boris-kz @khanh93vn https://github.com/khanh93vn

def hypot_g(blob): # redefine master blob by reduced g and increased ave * 2: variable costs of comp_angle

mask = ~blob.map[:, :, np.newaxis].repeat(4, axis=2) # stack map 4 times to fit the shape of dert__: (width, height, number of params)

https://github.com/boris-kz/CogAlg/blob/d2974597577b4db27510db2accd28fc6314f4c49/frame_2D_alg/comp_range.py#L11

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/boris-kz/CogAlg/issues/24, or mute the thread https://github.com/notifications/unsubscribe-auth/AUAXGa0iv0e4rkj1uolUvgQ0NQC8qK4-ks5vY-dBgaJpZM4cCRqz .

khanh93vn commented 5 years ago

The blob's mask is marking the coordinates of the included pixels?

Yes, blobs are of arbitrary shapes so when slicing the global map of pixels to get blob.dert__, most likely it'll include pixels that are not belong to the blob. So I used a boolean array to indicate that.

At first I used numpy fancy indexing for in-blob computations, but later switched to masked array for less code, fancy indexing is saved for more specific computations.

In fancy indexing, computations take place where boolean value is True so blob.map is True where pixel is included in blob. Masked array, on the other hand, only carry out computations where mask is False so it is inverted to become mask.

Actually, mask should be apply immediately when blob is formed, as blob.map have no other purpose.

Twenkid commented 5 years ago

Thanks! I got that the box is a bounding box, while the blob's segments are "hairy" and the inversion is to invert the processed regions and process the other ones, but I've missed the inverted behavior of masked array and fancy indexing.

Actually, mask should be apply immediately when blob is formed, as blob.map have no other purpose.

OK, and that way it could be done once in place, currently it's called for each derivative channel and creates new variables with the same content. ...

I see also a mask inversion in form_P and master_blob of generic_branch, which in form_P is done to a variable called "mask", which as far as I follow the code is the .mask attribute of the new_dert_ (and a sliced dert) which is defined as a masked array:

def master_blob(blob, branch_comp, new_params=True):
if blob.new_dert__[0].mask.all():

Unlike the map which is a regular numpy array, but is then used to create a mask of a masked array.

def form_P_(y, master_blob):    # cluster and sum horizontally consecutive pixels and their derivatives into Ps
    rng = master_blob.rng
    dert__ = master_blob.new_dert__[0]
    P_ = deque()  # initialize output
    dert_ = dert__[y, :, :]  # row of pixels + derivatives
    P_map_ = ~dert_.mask[:, 3]  # dert_.mask?

Code-reading wise in the beginning this was confusing to me (map and mask).

I think it would be helpful to mark explicitly in comments when a map is used for fancy indexing and when it's mask with the negated behavior, mostly for the the first-time encounter with the code.

Also if there is a sequence of negations (if done once in place initially) and then there's a hard to follow branching of inversions (haven't gone so deep yet), a flag may help avoid the map being in the wrong state.

Or then the negation should be done each time to a new variable and the original map itself should remain in its default state.

As of intra_blob:

Is this the entry point?

def intra_blob_root(frame): # simplified initial branch + eval_layer

boris-kz commented 5 years ago

Todor, entry point is frame_blobs, it calls intra_blob_root. Which is under revision, we should talk if you want to get into it

On Fri, Mar 22, 2019, 4:02 AM Todor Arnaudov notifications@github.com wrote:

Thanks! I got that the box is a bounding box, while the blob's segments are "hairy" and the inversion is to invert the processed regions and process the other ones, but I've missed the inverted behavior of masked array and fancy indexing.

Actually, mask should be apply immediately when blob is formed, as blob.map have no other purpose.

OK, and that way it could be done once in place, currently it's called for each derivative channel and creates new variables with the same content. ...

I see also a mask inversion in form_P and master_blob of generic_branch, which in form_P is done to a variable called "mask", which as far as I follow the code is the .mask attribute of the new_dert_ (and a sliced dert) which is defined as a masked array:

def master_blob(blob, branch_comp, new_params=True): if blob.new_dert__[0].mask.all():

Unlike the map which is a regular numpy array, but is then used to create a mask of a masked array.

def formP(y, master_blob): # cluster and sum horizontally consecutive pixels and their derivatives into Ps rng = master_blob.rng dert = master_blob.new_dert[0] P = deque() # initialize output dert = dert__[y, :, :] # row of pixels + derivatives Pmap = ~dert.mask[:, 3] # dert.mask?

Code-reading wise in the beginning this was confusing to me with the ntblob dert.map and their inversions, and now it's inverted again.

I think it would be helpful to mark explicitly in comments when a map is used for fancy indexing and when it's mask with the negated behavior, mostly for the the first-time encounter with the code.

Also if there is a sequence of negations (if done once in place initially) and then there's a hard to follow branching of inversions (haven't gone so deep yet), a flag may help avoid the map being in the wrong state.

Or then the negation should be done each time to a new variable and the original map itself should remain in its default state.

As of intra_blob:

Is this the entry point?

def intra_blob_root(frame): # simplified initial branch + eval_layer

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/boris-kz/CogAlg/issues/24#issuecomment-475527207, or mute the thread https://github.com/notifications/unsubscribe-auth/AUAXGUpQaDx3LIIb3z96eYBeRR4uVyNiks5vZI4UgaJpZM4cCRqz .

Twenkid commented 5 years ago

On Fri, Mar 22, 2019 at 12:59 PM Boris Kazachenko notifications@github.com wrote:

Todor, entry point is frame_blobs, it calls intra_blob_root.

Aha, I see - the commented code in frame_blobs.py global part.

Which is under revision, we should talk if you want to get into it

OK, after I study the code offline for a bit more.

You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/boris-kz/CogAlg/issues/24#issuecomment-475577032, or mute the thread https://github.com/notifications/unsubscribe-auth/AWSP2L4-7PhaCQVvmmazNqllKvJhja01ks5vZLeOgaJpZM4cCRqz .