gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master e41b38d: ConvertType converts RGB to HSV with


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e41b38d: ConvertType converts RGB to HSV with new --rgbtohsv option
Date: Sun, 23 Dec 2018 19:10:19 -0500 (EST)

branch: master
commit e41b38d4f52f9b4fbac21660a94048d3d49614eb
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    ConvertType converts RGB to HSV with new --rgbtohsv option
    
    With this new option, it is now possible to convert the the RGB input
    channels to HSV (stored as a FITS image).
---
 NEWS                    |   2 +
 bin/convertt/args.h     |  14 ++++++
 bin/convertt/color.c    | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
 bin/convertt/color.h    |   3 ++
 bin/convertt/convertt.c |   2 +
 bin/convertt/main.h     |   1 +
 bin/convertt/ui.h       |   1 +
 doc/gnuastro.texi       |  11 +++++
 8 files changed, 159 insertions(+)

diff --git a/NEWS b/NEWS
index 27b3712..bf2af0a 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,8 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
       (like JPEG, or PDF). Until now, the only available mapping was
       grayscale. Now "Hue, Saturation, Value" (HSV) and "SLS" (from SAO
       DS9) colormaps are also supported.
+    --rgbtohsv: Convert the RGB input channels to HSV (when the output is
+      in FITS format).
 
   Convolve:
     - Convolves 1D arrays (table columns, for example spectra)
diff --git a/bin/convertt/args.h b/bin/convertt/args.h
index 5a650e7..39fedda 100644
--- a/bin/convertt/args.h
+++ b/bin/convertt/args.h
@@ -97,6 +97,20 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_SET,
       gal_options_parse_csv_strings
     },
+    {
+      "rgbtohsv",
+      UI_KEY_RGBTOHSV,
+      0,
+      0,
+      "Convert RGB input into HSV (in FITS output)",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->rgbtohsv,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+
 
 
 
diff --git a/bin/convertt/color.c b/bin/convertt/color.c
index d67a1d2..ac23269 100644
--- a/bin/convertt/color.c
+++ b/bin/convertt/color.c
@@ -33,6 +33,15 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
+
+
+/***********************************************************************/
+/**************            From mono-channel           *****************/
+/***********************************************************************/
+/* This algorithm is a translation of the primary algorithm in this page:
+https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
 */
 void
 color_from_mono_hsv(struct converttparams *p)
 {
@@ -399,3 +408,119 @@ color_from_mono_sls(struct converttparams *p)
   /* Clean up. */
   gal_data_free(channel);
 }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************************************************************/
+/**************            From mono-channel           *****************/
+/***********************************************************************/
+/* This algorithm is a translation of the primary algorithm in this page:
+https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
 */
+void
+color_rgb_to_hsv(struct converttparams *p)
+{
+  float *h, *s, *v;
+  gal_data_t *H, *S, *V;
+  uint8_t *r, *g, *b, *rr, min, max, delta;
+
+  /* Basic sanity checks. */
+  if(gal_list_data_number(p->chll)!=3)
+    error(EXIT_FAILURE, 0, "%s: three color channels must be input",
+          __func__);
+  if( p->chll->type!=GAL_TYPE_UINT8
+      || p->chll->next->type!=GAL_TYPE_UINT8
+      || p->chll->next->next->type!=GAL_TYPE_UINT8 )
+    error(EXIT_FAILURE, 0, "when converting RGB to HSV, all three input "
+          "color channels must have an 8-bit unsigned integer type");
+
+  /* Allocate the three datasets to keep the RGB colors. */
+  H=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
+                   p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
+                   "HUE", NULL, NULL);
+  S=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
+                   p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
+                   "SATURATION", NULL, NULL);
+  V=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
+                   p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
+                   "VALUE", NULL, NULL);
+
+  /* Initiate the pointer arrays. */
+  h=H->array;
+  s=S->array;
+  v=V->array;
+  r=p->chll->array;
+  g=p->chll->next->array;
+  b=p->chll->next->next->array;
+
+  /* Parse the dataset and do the conversion. */
+  rr=r+p->chll->size;
+  do
+    {
+      /* Get the minimum and maximum RGB values. */
+      min = *r  < *g ? *r  : *g;
+      min = min < *b ? min : *b;
+      max = *r  > *g ? *r  : *g;
+      max = max > *b ? max : *b;
+
+      /* The "value" is the maximum. */
+      *v = (float)(max)/255.0;
+
+      /* See what the difference between the minimum and maximum are. */
+      delta=max-min;
+      if(delta)
+        {
+          if(max)
+            {
+              /* Set the Saturation and hue. */
+              *s = (float)(delta)/(float)(max);
+              *h = ( *r==max
+                     /* Between yellow and magenta. */
+                     ? ((float)(*g-*b)/(float)(delta))
+                     : ( *g==max
+                         /* Between cyan & yellow. */
+                         ? (2.0+(float)(*b-*r)/(float)(delta))
+                         /* Between magenta & cyan. */
+                         : (4.0+(float)(*r-*g)/(float)(delta)) ) );
+
+              /* Correct the hue: */
+              *h *= 60.0;
+              if( *h<0.0 ) *h += 360.0;
+            }
+          else
+            /* When `max==0', then *r=*g=*b=0, so s=h=0. */
+            *s=*h=0.0;
+        }
+      else
+        /* When there is no difference, then its actually a grayscale
+           dataset, so `*v' is the only parameter that matters. */
+        *s=*h=0.0;
+
+
+      /* Increment all the pointers. */
+      ++g; ++b; ++h; ++s; ++v;
+    }
+  while(++r<rr);
+
+  /* Free the old channels linked list and replace it with the new ones. */
+  gal_list_data_free(p->chll);
+  p->chll=H;
+  p->chll->next=S;
+  p->chll->next->next=V;
+}
diff --git a/bin/convertt/color.h b/bin/convertt/color.h
index 00281d3..252724b 100644
--- a/bin/convertt/color.h
+++ b/bin/convertt/color.h
@@ -29,4 +29,7 @@ color_from_mono_hsv(struct converttparams *p);
 void
 color_from_mono_sls(struct converttparams *p);
 
+void
+color_rgb_to_hsv(struct converttparams *p);
+
 #endif
diff --git a/bin/convertt/convertt.c b/bin/convertt/convertt.c
index 016f2f5..692351c 100644
--- a/bin/convertt/convertt.c
+++ b/bin/convertt/convertt.c
@@ -343,6 +343,8 @@ convertt(struct converttparams *p)
     {
     /* FITS: a FITS file can have many extensions (channels). */
     case OUT_FORMAT_FITS:
+      if(p->numch==3 && p->rgbtohsv)
+        color_rgb_to_hsv(p);
       for(channel=p->chll; channel!=NULL; channel=channel->next)
         gal_fits_img_write(channel, p->cp.output, NULL, PROGRAM_NAME);
       break;
diff --git a/bin/convertt/main.h b/bin/convertt/main.h
index f3d4f0f..cb462a0 100644
--- a/bin/convertt/main.h
+++ b/bin/convertt/main.h
@@ -86,6 +86,7 @@ struct converttparams
   uint32_t      borderwidth;  /* Width of border in PostScript points. */
   uint8_t               hex;  /* Use hexadecimal not ASCII85 encoding. */
   gal_data_t      *colormap;  /* Color space to use for single/mono.   */
+  uint8_t          rgbtohsv;  /* Convert input RGB channels to HSV.    */
   char          *fluxlowstr;  /* Lower flux truncation value.          */
   char         *fluxhighstr;  /* Higher flux truncation value.         */
   uint8_t           maxbyte;  /* Maximum byte value.                   */
diff --git a/bin/convertt/ui.h b/bin/convertt/ui.h
index 44ef6eb..5e91622 100644
--- a/bin/convertt/ui.h
+++ b/bin/convertt/ui.h
@@ -64,6 +64,7 @@ enum option_keys_enum
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
   UI_KEY_COLORMAP            = 1000,
+  UI_KEY_RGBTOHSV,
 };
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 15a5017..35f59af 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -10844,6 +10844,17 @@ unlike the HSV color range, it includes black and 
white and brighter colors
 (like yellow, red and white) show the larger values.
 @end table
 
address@hidden --rgbtohsv
+When there are three input channels and the output is in the FITS format,
+interpret the three input channels as red, green and blue channels (RGB)
+and convert them to the hue, saturation, value (HSV) color space.
+
+The currently supported output formats of ConvertType don't have native
+support for HSV. Therefore this option is only supported when the output is
+in FITS format and each of the hue, saturation and value arrays can be
+saved as one FITS extension in the output for further analysis (for example
+to select a certain color).
+
 @end table
 
 @noindent



reply via email to

[Prev in Thread] Current Thread [Next in Thread]