Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[FEAT] Add dilate and erode operations to Tensor#1136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
BritishWerewolf wants to merge3 commits intohuggingface:main
base:main
Choose a base branch
Loading
fromBritishWerewolf:add-dilate-erode

Conversation

BritishWerewolf
Copy link
Contributor

@BritishWerewolfBritishWerewolf commentedJan 4, 2025
edited
Loading

This PR is inspired by the functionality ofOpenCV.

With this, we can create a kernel that is operated over each element of thedata array and performs some calculation.
For this PR, we only havedilate anderode.

I decided to set these functions toasync, despite that makingthe chaining a bit clunkier, since these functions are often used together.


Explanation

kernel

This is an array of 0s and 1s that will be applied to each element of thedata array, 1 by 1.

There are multiple shapes supported in this PR, they are:RECT,CROSS,ELLIPSE.
Consider a 5x5 kernel for each shape:

  • RECT:
    1 1 1 1 11 1 1 1 11 1 1 1 11 1 1 1 11 1 1 1 1
  • CROSS:
    0 0 1 0 00 0 1 0 01 1 1 1 10 0 1 0 0 0 0 1 0 0
  • ELLIPSE:
    0 0 1 0 00 1 1 1 01 1 1 1 10 1 1 1 0 0 0 1 0 0

The element we are checking will be in the centre, and then it will apply this kernel to all those values around it.
Any value of 1 will be included and 0 will be discarded.

dilate

Once we have a list of values for that element, we will apply aMath.max to return the biggest value of these.

Consider this Tensor.

 1  2  3  4  5 6  7  8  9 1011 12 13 14 1516 17 18 19 2021 22 23 24 25

If we were to applyCROSS with a kernel size of 3x3, then the first iteration would return the values of[1, 2, 6]. This is because the top and left side of the kernel are off the edge.

When the loop gets to the value of13, the extracted values would be[8, 12, 13, 14, 18].

Finally, the value in each instance will be replaced with the maximum value.
Again, in the case of the first element, that would be6 and for the centre element, that would be replaced with18.

erode

This works in the exact same way asdilate, however it will apply theMath.min to the elements instead.

Comment on lines +902 to +911
// Only include values where the kernel has a value
// of 1.
// Rather than multiply against this value, we use
// the if check to reduce the size of the array.
const kernelValue = kernel[kernelRowOffset + paddingSize.height][kernelColOffset + paddingSize.width];
if (kernelValue === 1) {
kernelValues.push(data[neighborIndex] * kernelValue);
}
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Originally I was not using the if statement, and utilising the fact that a kernel contains either0 or1, however that meant thatkernelValues array would be bigger than it needs to be.

Also,erode wouldn't work properly because0 is always the minimum value.

Comment on lines +1769 to +1779
function validateKernel(kernelSize) {
let kernel;
if (typeof kernelSize === 'object' && 'width' in kernelSize && 'height' in kernelSize) {
// This is a Size object, so no conversion required.
kernel = kernelSize;
} else if (typeof kernelSize === 'number' && Number.isInteger(kernelSize)) {
// A single whole number is assumed as the width and height.
kernel = { width: kernelSize, height: kernelSize };
} else if (Array.isArray(kernelSize) && kernelSize.length === 2 && kernelSize.every(Number.isInteger)) {
// An array of two values is assumed as width then height.
kernel = { width: kernelSize[0], height: kernelSize[1] };
} else {
throw new Error("Invalid kernel size.");
}

if (kernel.width % 2 === 0 || kernel.height % 2 === 0) {
throw new Error("Kernel size must be odd");
}

return kernel;
}
Copy link
ContributorAuthor

@BritishWerewolfBritishWerewolfJan 4, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The purpose of this function is to help users with passing in kernel values.

To get a 3x3 kernel to theerode function we can do this:

  • tensor.erode(3)
  • tensor.erode([3, 3])
  • tensor.erode({ width: 3, height: 3 })

Most likely we want a symmetrical kernel, and it's easier to just pass in a single number.

@BritishWerewolfBritishWerewolf marked this pull request as ready for reviewJanuary 4, 2025 01:43
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

1 participant
@BritishWerewolf

[8]ページ先頭

©2009-2025 Movatter.jp