-
Notifications
You must be signed in to change notification settings - Fork 61
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
turn a picture to black and white #243
Comments
Hello @floodico, One way would be:
https://libvips.github.io/libvips/API/current/libvips-colour.html#vips-colourspace |
This might be helpful. Did I do this right @jcupitt? Am I doing anything silly? Black and white thresholding with VIPS in C. https://gist.github.com/angstyloop/37d4454442beea452b718bb11469f2a4 |
Hi @angstyloop, in fact you can do this with just libvips operators -- you need https://www.libvips.org/API/current/libvips-arithmetic.html#vips-more-const1 I'd also set sequential mode, so maybe (untested): #include <vips/vips.h>
int main (int argc, char** argv) {
if (argc != 4) {
printf("USAGE: %s <THRESHOLD (0-255)> <INPUT_IMAGE> <OUTPUT_IMAGE>\n",
argv[0]);
vips_error_exit(NULL);
}
if (VIPS_INIT(argv[0]))
vips_error_exit(NULL);
VipsImage *in, *out;
double threshold = strtod(argv[1], NULL);
if (!(in = vips_image_new_from_file(argv[2],
"access", VIPS_ACCESS_SEQUENTIAL,
NULL)))
vips_error_exit(NULL);
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_more_const1(in, &out, threshold, NULL))
vips_error_exit(NULL);
g_object_unref(in);
in = out;
if (vips_image_write_to_file(in, argv[3], NULL))
vips_error_exit(NULL);
g_object_unref(in);
return EXIT_SUCCESS;
} |
The libvips C API has local objects, which can be a useful way to express something like this more concisely. If you write: VipsObject *context = (VipsObject *) vips_image_new();
VipsImage **t = (VipsImage **) vips_object_local_array( context, 4 ); That makes a dummy VipsObject (called context) that does nothing. It then makes This lets you chain libvips operators, eg.: #include <vips/vips.h>
int main (int argc, char** argv) {
if (VIPS_INIT(argv[0]))
vips_error_exit(NULL);
if (argc != 4) {
printf("USAGE: %s <THRESHOLD (0-255)> <INPUT_IMAGE> <OUTPUT_IMAGE>\n",
argv[0]);
vips_error_exit(NULL);
}
VipsObject *context = (VipsObject *) vips_image_new();
VipsImage **t = (VipsImage **) vips_object_local_array( context, 4 );
double threshold = strtod(argv[1], NULL);
if (!(t[0] = vips_image_new_from_file(argv[2], "access", VIPS_ACCESS_SEQUENTIAL, NULL)) ||
vips_colourspace(t[0], &t[1], VIPS_INTERPRETATION_B_W, NULL) ||
vips_extract_band(t[1], &t[2], 0, "n", 1, NULL) ||
vips_more_const1(t[2], &t[3], threshold, NULL) ||
vips_image_write_to_file(t[3], argv[3], NULL)) {
g_object_unref(context);
vips_error_exit(NULL);
}
g_object_unref(context);
return EXIT_SUCCESS;
} It's a bit annoying to have to keep track of all the In larger programs, there's usually something already there you can use as |
This is legit @jcupitt thanks so much! |
For anyone reading, interested in the BW thresholding in C, and scratching their heads at vips_more_const ... It's clear what it is from the docs, which are excellent. But if you just want a summary here - it literally means "true iff the pixel value is greater than the given constant". In other words, it is a step function of height one, where you get to pick the position of the jump discontinuity. Digging into the other operators, I see lots of other cool ways to create "boolean" images like the one described. "Thresholding" images with VIPS in C is really easy, once you know how to use these simple relational operations. VIPS just doesn't use the word "thresholding" for this - that means something different in VIPS land. I don't think there is really a term VIPS uses to describe these, but I've seen them referred to as "boolean" images which is why I adopted that term. Note: VIPS uses the word "more" instead of "greater", which I like. https://www.libvips.org/API/8.6/libvips-arithmetic.html#vips-more-const1 Update: I actually needed to use vips_moreeq_const1 instead, to get the behavior I wanted. The pixels that are more than or equal to the threshold should be black, and the pixels that are less than the threshold should be white. Using vips_more_const1, the program behaves correctly except when the threshold is equal to zero. The desired behavior there is all white pixels, but in the previous examples using vips_more_const1, they were black, which makes sense. This is just the typical < vs <= DOH! moment. |
Also, I learned about sequential access. Here is an excerpt about it from the VIPS docs:
https://www.libvips.org/API/8.6/How-it-opens-files.md.html You get an opportunity to use |
I was able to compile and run the first revised example from above: https://gist.github.com/angstyloop/7d14dcd9b0bdc57cffb849282a74c354 |
I was able to compile and run the second revised example from above: https://gist.github.com/angstyloop/38aa2ceca01b592f4ca358f58d0ae3e0 |
Hey there. How can use this to make an bw effect?
The text was updated successfully, but these errors were encountered: