I try to implement a method to segment image with seed points, and assign each pixel to nearest point.
for example, if the pixel close to 1, then set to 1.
input:
0 0 0 0 0 3 0
0 1 0 0 0 0 0
0 0 0 0 2 0 0
0 0 0 0 0 0 0
output:
1 1 1 3 3 3 3
1 1 1 2 2 3 3
1 1 1 2 2 2 2
1 1 1 2 2 2 2
current the method take too long time and calculate (width * height * numPoints) times, is there any algorithm can be faster?
7 seconds to process 5 9478 * 1868 images, numPoints = 8
for (int i = 0; i < height; i )
{
for (int j = 0; j < width; j )
{
byte index = 0;
double distance = double.MaxValue;
for (int m = 0; m < elements.Count; m )
{
CircleROI circle = roiResized[m];
double currentDistance = Math.Abs(i - circle.Center.Y)
Math.Abs(j - circle.Center.X);
if (currentDistance < distance)
{
distance = currentDistance;
index = (byte)m;
}
}
*data = index;
}
}
CodePudding user response:
You can make your program work in time proportional to the number of pixels.
If you just want to stick to single-channel greyscale, rather than colour, you can use:
magick -size 60x30- xc: \
-sparse-color Voronoi '10,10 black 40,20 gray 50,0 white' result.png
There is an excellent discussion and tutorial on this and similar techniques by Anthony Thyssen here.
It is related to the "Delaunay Triangulation" and, though I have not tested it, I expect the OpenCV implementation will be extremely fast.