Evaluate check box from a scanned image in node.js


I want to evaluate checkbox is checked or not from a scanned image. I found the node module like node-dv and node-fv for this. But when to install this I got the following error on mac.

../deps/opencv/modules/core/src/arithm1.cpp:444:51: error: constant expression evaluates to 4294967295 which cannot be narrowed to type 'int' [-Wc++11-narrowing]
static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff };
                                                  ^~~~~~~~~~
../deps/opencv/modules/core/src/arithm1.cpp:444:51: note: insert an explicit cast to silence this issue
static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff };
                                                  ^~~~~~~~~~
                                                  static_cast<int>( )
../deps/opencv/modules/core/src/arithm1.cpp:444:75: error: constant expression evaluates to 4294967295 which cannot be narrowed to type 'int' [-Wc++11-narrowing]
static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff };
                                                                          ^~~~~~~~~~
../deps/opencv/modules/core/src/arithm1.cpp:444:75: note: insert an explicit cast to silence this issue
static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff };
                                                                          ^~~~~~~~~~
                                                                          static_cast<int>( )
2 errors generated.
make: *** [Release/obj.target/libopencv/deps/opencv/modules/core/src/arithm1.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/entapzian/.nvm/versions/node/v4.3.1/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:270:23)
gyp ERR! stack     at emitTwo (events.js:87:13)
gyp ERR! stack     at ChildProcess.emit (events.js:172:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)

Is the above dependency is the best solution for my problem? If not please suggest me a good solution.

Answer

Sorry for the delayed answer, I've been really busy yesterday and today. Here is an example that grabs predefined regions of an image and determines if the checkboxes are filled or empty. This is only a starting point, and can probably be greatly improved, but it should work if the scanned image is of decent quality.

The first step is getting the image's pixels. Next, you get the regions in the image that contain the checkboxes by grabbing them according to a pattern. Last, you evaluate whether or not the checkbox is checked by comparing the average brightness of that region in the image to the baseline brightness of an unchecked box.

I recommend using the get-pixels Node.js package to get the image pixels.

Here's an example that you can probably adjust to suit your needs:

var get_pixels = require(‘get-pixels’);
var image_uri = 'path_to_image';

get_pixels(image_uri, process_image);

var pattern_width = 800, // Width of your pattern image
    pattern_height = 1100; // Height of your pattern image

// The pattern image doesn't need to be loaded, you just need to use its dimensions to reference the checkbox regions below
// This is only for scaling purposes in the event that the scanned image is of a higher or lower resolution than what you used as a pattern.

var checkboxes = [
    {x1: 10, y1: 10, x2: 30, y2: 30}, // Top left and bottevent that the scanned image is of a higher or lower resolution than what you used as a pattern.

var checkboxes = [
    {x1: 10, y1: 10, x2: 30, y2: 30}, // Top left and bottom right corners of the region containing the checkbox
    {x1: 10, y1: 60, x2: 30, y2: 80}
];

// You'll need to get these by running this on an unchecked form and logging out the adjusted_average of the regions
var baseline_average = ??, // The average brightness of an unchecked region
    darkness_tolerance = ??; // The offset below which the box is still considered unchecked

function process_image(err, pixels) {

    if (!err) {

        var regions = get_regions(pixels);

        var checkbox_states = evaluate_regions(regions);

        // Whatever you want to do with the determined states

    }else{
        console.log(err);
        return;
    }

}

function get_regions(pixels) {

    var regions = [], // Array to hold the pixel data from selected regions
        img_width = pixels.shape[0], // Get the width of the image being processed
        img_height = pixels.shape[1], // Get the height
        scale_x = img_width / pattern_width, // Get the width scale difference between pattern and image (for different resolution scans)
        scale_y = img_height / pattern_height; // Get the height scale difference

    for (var i = 0; i < checkboxes.length; i++) {

        var start_x = Math.round(checkboxes[i].x1 * scale_x),
            start_y = Math.round(checkboxes[i].y1 * scale_y),
            end_x = Math.round(checkboxes[i].x2 * scale_x),
            end_y = Math.round(checkboxes[i].y2 * scale_y),
            region = [];

        for (var y = start_y; y <= end_y; y++) {
            for (var x = start_x; y <= end_x; x++) {
                region.push(
                    pixels.get(x, y, 0), // Red channel
                    pixels.get(x, y, 1), // Green channel
                    pixels.get(x, y, 2), // Blue channel
                    pixels.get(x, y, 3) // Alpha channel
                );
            }
        }

        regions.push(region);

    }

    return regions;

}

function evaluate_regions(regions) {

    var states = [];

    for (var i = 0; i < regions.length; i++) {

        var brightest_value = 0,
            darkest_value = 255,
            total = 0;

        for (var j = 0; j < regions[i].length; j+=4) {

            var brightness = (regions[i][j] + regions[i][j + 1] + regions[i][j + 2]) / 3; // Pixel brightness
            if (brightness > brightest_value) brightest_value = brightness;
            if (brightness < darkest_value) darkest_value = brightness;
            total += brightness;

        }

        var adjusted_average = (total / (regions[i].length / 4)) - darkest_value; // Adjust contrast
        var checked = baseline_average - adjusted_average > darkness_tolerance ? true : false;

        states.push(checked);

    }

    return states;

} 
source: stackoverflow.com
js interview questions