Created
March 5, 2023 01:29
-
-
Save angstyloop/37d4454442beea452b718bb11469f2a4 to your computer and use it in GitHub Desktop.
Threshold an image to black and white with the amazing open-source VIPS C library for image processing. Create a "binary image".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** threshold.c | |
Create a "binary image" from an image - an image with only black (rgb(0, 0, 0)) | |
and white (rgb(255, 255, 255)) pixels, based on a cutoff threshold for the pixel | |
values of the grayscale image. Pixel values above the threshold are set to 255, | |
255, and pixel values below the threshold are set to 0, in the new image. | |
COMPILE | |
gcc -o threshold threshold.c `pkg-config vips --cflags --libs` | |
EXAMPLE USAGE | |
./threshold 128 in.png out.png | |
*/ | |
#include <vips/vips.h> | |
typedef guint8 PixelRGB[1]; | |
int main (int argc, char** argv) { | |
if (argc != 4 || !argv[1][0] || !argv[2][0] || !argv[3][0]) { | |
printf("USAGE: %s <THRESHOLD (0-255)> <IMAGE_PATH>\n", argv[0]); | |
vips_error_exit(NULL); | |
} | |
if (VIPS_INIT(argv[0])) | |
vips_error_exit(NULL); | |
VipsImage* in, * out; | |
unsigned long threshold_ = strtoul(argv[1], NULL, 10); | |
guint8 threshold = threshold_ < 0 ? 0 : threshold_ > 255 ? 255 : threshold_; | |
if (!(in = vips_image_new_from_file(argv[2], NULL))) | |
vips_error_exit(NULL); | |
guint width = in->Xsize; | |
guint height = in->Ysize; | |
if (vips_colourspace(in, &out, VIPS_INTERPRETATION_B_W, NULL)) | |
vips_error_exit(NULL); | |
g_object_unref(in); | |
in = out; | |
if (vips_extract_band(in, &out, 0, "n", 1, NULL)) | |
vips_error_exit(NULL); | |
g_object_unref(in); | |
in = out; | |
if (vips_image_wio_input(in)) | |
vips_error_exit(NULL); | |
PixelRGB* pixels = (PixelRGB*) VIPS_IMAGE_ADDR(in, 0, 0); | |
VipsPel* pels = VIPS_ARRAY(NULL, width * height, VipsPel); | |
for (int i = 0; i < width * height; ++i) | |
pels[i] = pixels[i][0] < threshold ? 0 : 255; | |
g_object_unref(in); | |
in = out; | |
if (!(in = vips_image_new_from_memory_copy(pels, width * height, | |
width, height, 1, VIPS_FORMAT_UCHAR))) | |
vips_error_exit(NULL); | |
if (vips_image_write_to_file(in, argv[3], NULL)) | |
vips_error_exit(NULL); | |
g_object_unref(in); | |
in = out; | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment