-
Notifications
You must be signed in to change notification settings - Fork 177
Added new module i.spec.convexhull #1433
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: grass8
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
clang-format
[clang-format] reported by reviewdog 🐶
| create_group(output_group->answer); |
[clang-format] reported by reviewdog 🐶
| add_file_to_group(output_group->answer, outname[i], G_mapset()); |
[clang-format] reported by reviewdog 🐶
grass-addons/src/imagery/i.spec.convexhull/main.c
Lines 155 to 156 in 31455c3
| if (infd[i] >= 0) Rast_close(infd[i]); | |
| if (outfd[i] >= 0) Rast_close(outfd[i]); |
| double y; | ||
| } Point; | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
|
|
||
|
|
||
| // Function to calculate the orientation of three points (p, q, r) | ||
| double orientation(Point p, Point q, Point r) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| double orientation(Point p, Point q, Point r) { | |
| double orientation(Point p, Point q, Point r) | |
| { |
| } | ||
|
|
||
| // Function to find the convex hull of a set of points | ||
| void convexHull(Point *points, int n, Point *hull, int *hullSize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| void convexHull(Point *points, int n, Point *hull, int *hullSize) { | |
| void convexHull(Point *points, int n, Point *hull, int *hullSize) | |
| { |
| // Storage for the convex hull | ||
| *hullSize = 0; | ||
|
|
||
| // Start from the leftmost point and move clockwise until the point with maximum x-coordinate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| // Start from the leftmost point and move clockwise until the point with maximum x-coordinate | |
| // Start from the leftmost point and move clockwise until the point with | |
| // maximum x-coordinate |
| // Add the current point to the result | ||
| hull[(*hullSize)++] = points[p]; | ||
|
|
||
| // Search for a point 'q' such that orientation(p, q, x) is clockwise for all points 'x' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| // Search for a point 'q' such that orientation(p, q, x) is clockwise for all points 'x' | |
| // Search for a point 'q' such that orientation(p, q, x) is clockwise | |
| // for all points 'x' |
| // Load nrows and ncols | ||
| nrows = Rast_window_rows(); | ||
| ncols = Rast_window_cols(); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| Rast_get_row(infd[i], inbuf[i], row, DCELL_TYPE); | ||
| } | ||
| // Process each column (pixel spectrum reconstitution) | ||
| //#pragma omp parallel for private(i, din, dout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| //#pragma omp parallel for private(i, din, dout) | |
| // #pragma omp parallel for private(i, din, dout) |
| din[i] = ((double *)inbuf[i])[col]; | ||
| } | ||
| // Process convex hull per spectrum | ||
| convexhull(din, dout, ref.nfiles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| convexhull(din, dout, ref.nfiles); | |
| convexhull(din, dout, ref.nfiles); |
| // Clean the output_group from any pre-existing list | ||
| if (I_find_group(output_group->answer)) { | ||
| if (!G_check_overwrite(argc, argv)) { | ||
| G_fatal_error(_("Group <%s> exists. Use --overwrite to replace."), output_group->answer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| G_fatal_error(_("Group <%s> exists. Use --overwrite to replace."), output_group->answer); | |
| G_fatal_error(_("Group <%s> exists. Use --overwrite to replace."), | |
| output_group->answer); |
| create_group(output_group->answer); | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| create_group(output_group->answer); | |
| } else { | |
| create_group(output_group->answer); | |
| } | |
| else { |
| #%module | ||
| #% description: Export moving window samples from an imagery group and two rasters. | ||
| #% keyword: imagery | ||
| #% keyword: ANN | ||
| #% keyword: training | ||
| #% keyword: export | ||
| #%end | ||
| #%option G_OPT_I_GROUP | ||
| #% description: Imagery group name | ||
| #% required: yes | ||
| #%end | ||
| #%option G_OPT_R_INPUT | ||
| #% key: raster1 | ||
| #% description: First raster input (clump) | ||
| #% required: yes | ||
| #%end | ||
| #%option G_OPT_R_INPUT | ||
| #% key: raster2 | ||
| #% description: Second raster input (value) | ||
| #% required: yes | ||
| #%end | ||
| #%option | ||
| #% key: output_directory | ||
| #% type: string | ||
| #% description: Output directory | ||
| #% required: yes | ||
| #%end | ||
| #%option | ||
| #% key: window_width | ||
| #% type: integer | ||
| #% description: Moving window width in cells | ||
| #% required: yes | ||
| #% answer: 128 | ||
| #%end | ||
| #%option | ||
| #% key: window_height | ||
| #% type: integer | ||
| #% description: Moving window height in cells | ||
| #% required: yes | ||
| #% answer: 128 | ||
| #%end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| #%module | |
| #% description: Export moving window samples from an imagery group and two rasters. | |
| #% keyword: imagery | |
| #% keyword: ANN | |
| #% keyword: training | |
| #% keyword: export | |
| #%end | |
| #%option G_OPT_I_GROUP | |
| #% description: Imagery group name | |
| #% required: yes | |
| #%end | |
| #%option G_OPT_R_INPUT | |
| #% key: raster1 | |
| #% description: First raster input (clump) | |
| #% required: yes | |
| #%end | |
| #%option G_OPT_R_INPUT | |
| #% key: raster2 | |
| #% description: Second raster input (value) | |
| #% required: yes | |
| #%end | |
| #%option | |
| #% key: output_directory | |
| #% type: string | |
| #% description: Output directory | |
| #% required: yes | |
| #%end | |
| #%option | |
| #% key: window_width | |
| #% type: integer | |
| #% description: Moving window width in cells | |
| #% required: yes | |
| #% answer: 128 | |
| #%end | |
| #%option | |
| #% key: window_height | |
| #% type: integer | |
| #% description: Moving window height in cells | |
| #% required: yes | |
| #% answer: 128 | |
| #%end | |
| # %module | |
| # % description: Export moving window samples from an imagery group and two rasters. | |
| # % keyword: imagery | |
| # % keyword: ANN | |
| # % keyword: training | |
| # % keyword: export | |
| # %end | |
| # %option G_OPT_I_GROUP | |
| # % description: Imagery group name | |
| # % required: yes | |
| # %end | |
| # %option G_OPT_R_INPUT | |
| # % key: raster1 | |
| # % description: First raster input (clump) | |
| # % required: yes | |
| # %end | |
| # %option G_OPT_R_INPUT | |
| # % key: raster2 | |
| # % description: Second raster input (value) | |
| # % required: yes | |
| # %end | |
| # %option | |
| # % key: output_directory | |
| # % type: string | |
| # % description: Output directory | |
| # % required: yes | |
| # %end | |
| # %option | |
| # % key: window_width | |
| # % type: integer | |
| # % description: Moving window width in cells | |
| # % required: yes | |
| # % answer: 128 | |
| # %end | |
| # %option | |
| # % key: window_height | |
| # % type: integer | |
| # % description: Moving window height in cells | |
| # % required: yes | |
| # % answer: 128 | |
| # %end |
| import grass.script as gs | ||
| from grass.script import array as garray | ||
|
|
||
| def read_group_bands(group_name): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| def read_group_bands(group_name): | |
| def read_group_bands(group_name): |
| from grass.script import array as garray | ||
|
|
||
| def read_group_bands(group_name): | ||
| bands = gs.read_command('i.group', group=group_name, format='shell').splitlines() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| bands = gs.read_command('i.group', group=group_name, format='shell').splitlines() | |
| bands = gs.read_command("i.group", group=group_name, format="shell").splitlines() |
| bands = gs.read_command('i.group', group=group_name, format='shell').splitlines() | ||
| return bands | ||
|
|
||
| def extract_window(array, row_off, col_off, height, width): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| def extract_window(array, row_off, col_off, height, width): | |
| def extract_window(array, row_off, col_off, height, width): |
| return bands | ||
|
|
||
| def extract_window(array, row_off, col_off, height, width): | ||
| return array[row_off:row_off+height, col_off:col_off+width] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| return array[row_off:row_off+height, col_off:col_off+width] | |
| return array[row_off : row_off + height, col_off : col_off + width] | |
| xres = (region['e'] - region['w']) / ncols | ||
| yres = (region['n'] - region['s']) / nrows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| xres = (region['e'] - region['w']) / ncols | |
| yres = (region['n'] - region['s']) / nrows | |
| xres = (region["e"] - region["w"]) / ncols | |
| yres = (region["n"] - region["s"]) / nrows |
| transform = from_origin(region['w'], region['n'], xres, yres) | ||
| wkt = gs.read_command('g.proj', flags='w').strip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| transform = from_origin(region['w'], region['n'], xres, yres) | |
| wkt = gs.read_command('g.proj', flags='w').strip() | |
| transform = from_origin(region["w"], region["n"], xres, yres) | |
| wkt = gs.read_command("g.proj", flags="w").strip() |
| idx = 0 | ||
| for row in range(0, nrows - window_height + 1, window_height): | ||
| for col in range(0, ncols - window_width + 1, window_width): | ||
| window_bands = [extract_window(b, row, col, window_height, window_width) for b in band_arrays] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| window_bands = [extract_window(b, row, col, window_height, window_width) for b in band_arrays] | |
| window_bands = [ | |
| extract_window(b, row, col, window_height, window_width) | |
| for b in band_arrays | |
| ] |
| for clump_id in clump_ids: | ||
| if clump_id == 0: | ||
| continue | ||
| mask = (win1 == clump_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| mask = (win1 == clump_id) | |
| mask = win1 == clump_id |
| out_group = os.path.join(out_subdir, f"group_{clump_id}_{corresponding_value}.tif") | ||
| export_multiband_geotiff([b * mask for b in window_bands], out_group, transform, crs) | ||
| out_r = os.path.join(out_subdir, f"{raster1}_clump{clump_id}_val{corresponding_value}.tif") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ruff] reported by reviewdog 🐶
| out_group = os.path.join(out_subdir, f"group_{clump_id}_{corresponding_value}.tif") | |
| export_multiband_geotiff([b * mask for b in window_bands], out_group, transform, crs) | |
| out_r = os.path.join(out_subdir, f"{raster1}_clump{clump_id}_val{corresponding_value}.tif") | |
| out_group = os.path.join( | |
| out_subdir, f"group_{clump_id}_{corresponding_value}.tif" | |
| ) | |
| export_multiband_geotiff( | |
| [b * mask for b in window_bands], out_group, transform, crs | |
| ) | |
| out_r = os.path.join( | |
| out_subdir, | |
| f"{raster1}_clump{clump_id}_val{corresponding_value}.tif", | |
| ) |
| create_group(output_group->answer); | ||
| } else { | ||
| // Proceed to create | ||
| create_group(output_group->answer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| create_group(output_group->answer); | |
| create_group(output_group->answer); |
|
|
||
| // Close files and add to group | ||
| for (i = 0; i < ref.nfiles; i++) { | ||
| add_file_to_group(output_group->answer, outname[i], G_mapset()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| add_file_to_group(output_group->answer, outname[i], G_mapset()); | |
| add_file_to_group(output_group->answer, outname[i], G_mapset()); |
| if (infd[i] >= 0) Rast_close(infd[i]); | ||
| if (outfd[i] >= 0) Rast_close(outfd[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clang-format] reported by reviewdog 🐶
| if (infd[i] >= 0) Rast_close(infd[i]); | |
| if (outfd[i] >= 0) Rast_close(outfd[i]); | |
| if (infd[i] >= 0) | |
| Rast_close(infd[i]); | |
| if (outfd[i] >= 0) | |
| Rast_close(outfd[i]); |
| @@ -0,0 +1,7 @@ | |||
| MODULE_TOPDIR = ../.. | |||
|
|
|||
| PGM = i.ann.mktrainset | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @YannChemin Please consider to submit the new i.ann.mktrainset addon as a separate pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
He is submitting PRs with the default branch, so that's what is happening. There isn't a branch for each of the PRs (and we get notified of his CI failures as that branch is involved in a PR we are involved in)
i.spec.convexhull
This module processes all raster bands in a GRASS imagery group, performing continuum removal via convex hull analysis on the spectral profile of each pixel. The result is a new group of raster maps, each corresponding to an input band, with the continuum-removed spectra.
This functionality is very commonly used in mineral mapping in specific parts of hyperspectral SWIR ranges.
Original Signatures

Convexhull applied to signatures
