Archives

Categories

Censoring Images

A client asked me to develop a system for “censoring” images from an automatic camera. The situation is that we have a camera taking regular photos from a fixed location which includes part of someone else’s property. So my client made a JPEG with some black rectangles in the sections that need to be covered. The first thing I needed to do was convert the JPEG to a PNG with transparency for the sections that aren’t to be covered.

To convert it I loaded the JPEG in the GIMP and went to the Layer->Transparency->Add Alpha Channel menu to enabled the Alpha channel. Then I selected the “Bucket Fill tool” and used “Mode Erase” and “Fill by Composite” and then clicked on the background (the part of the JPEG that was white) to make it transparent. Then I exported it to PNG.

If anyone knows of an easy way to convert the file then please let me know. It would be nice if there was a command-line program I could run to convert a specified color (default white) to transparent. I say this because I can imagine my client going through a dozen iterations of an overlay file that doesn’t quite fit.

To censor the image I ran the “composite” command from imagemagick. The command I used was “composite -gravity center overlay.png in.jpg out.jpg“. If anyone knows a better way of doing this then please let me know.

The platform I’m using is a ARM926EJ-S rev 5 (v5l) which takes 8 minutes of CPU time to convert a single JPEG at full DSLR resolution (4 megapixel). It also required enabling swap on a SD card to avoid running out of RAM and running “systemctl disable tmp.mount” to stop using tmpfs for /tmp as the system only has 256M of RAM.

6 comments to Censoring Images

  • Donald Gordon

    jpegtran can crop a JPEG without recompressing it. Could it be modified to blank rectangles instead?

  • Martin

    If I were the neighbour and would not want to be captured on my property, I would ask for a simple mechanical barrier, blocking the relevant part of the camera.

    It has a number of advantages:

    1. It it transparent even for non-technical people, that the camera would not capture areas that it shouldn’t.

    2. It consumes less energy than any computational work, therefore it is better for our climate.

    3. It can’t be hacked in secret, so that the removed parts of the pictures are stored elsewhere.

    Of course, that would work only for the future ;-)

  • My recommendation: Use pnmarith.

    Prepare the mask as a pbm file (white = unredacted, black=redacted).

    Your conversion pipeline becomes:
    `djpeg | pnmarith -minimum mask.pbm – | cjpeg`

    The main advantage of something as old as netpbm is it streams images rather than storing them all in RAM. So on desktop Linux with a 2560×1440 image, the `composite` workflow reports 69224 maxresident, while the `pnmarith` workflow reports only 1900 maxresident. It also takes less than half the CPU time, and appears to use integer arithmetic only based on a quick glance at the source. (in pnmarith. you can also explore whether cjpeg/djpeg `-dct int` make a performance difference on your target)

    If the size of the mask file on disk is important, gzip it and use the following (non-dash-compatible, unfortunately) syntax: `pnmarith -minimum – <(zcat mask.pbm.gz)`

    Apologies for any display errors, I hope this is useful.

  • I guess I’m missing something obvious here, but what about:
    convert source.jpg -transparent white target.png

  • Donald: thanks for the suggestion, I’ll try that out next time I’m working on such things.

    i5513: Thanks, I didn’t realise there was a Gimp batch mode.

    Martin: these things are being dealt with by other people and my job is to implement the decision that others have made. I’m happy to stick to my part.

    Jeff: thanks, that’s worth keeping in mind. I think I’ve solved the RAM issue, but it’s still better to be more efficient about such things.

    Tzafrir: the obvious thing is that the man page is long and complex and Google didn’t give the answer. Thanks for the suggestion I’ll do that next time then send me an image like that.