uk.ac.horizon.artcodes.process.TileThresholder.java Source code

Java tutorial

Introduction

Here is the source code for uk.ac.horizon.artcodes.process.TileThresholder.java

Source

/*
 * Artcodes recognises a different marker scheme that allows the
 * creation of aesthetically pleasing, even beautiful, codes.
 * Copyright (C) 2013-2016  The University of Nottingham
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published
 *     by the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package uk.ac.horizon.artcodes.process;

import android.content.Context;

import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.util.List;
import java.util.Map;

import uk.ac.horizon.artcodes.detect.DetectorSetting;
import uk.ac.horizon.artcodes.detect.ImageBuffers;
import uk.ac.horizon.artcodes.detect.handler.MarkerDetectionHandler;
import uk.ac.horizon.artcodes.model.Experience;
import uk.ac.horizon.artcodes.scanner.R;

public class TileThresholder implements ImageProcessor {
    public static class Factory implements ImageProcessorFactory {
        public String getName() {
            return "tile";
        }

        public ImageProcessor create(Context context, Experience experience, MarkerDetectionHandler handler,
                Map<String, String> args) {
            return new TileThresholder();
        }
    }

    private enum Display {
        none, greyscale, threshold;

        private static final Display[] vals = values();

        public Display next() {
            return vals[(this.ordinal() + 1) % vals.length];
        }
    }

    private transient int tiles = 1;
    private Display display = Display.none;

    public TileThresholder() {
    }

    @Override
    public void process(ImageBuffers buffers) {
        Mat image = buffers.getImageInGrey();
        Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);

        if (display == Display.greyscale) {
            Imgproc.cvtColor(image, buffers.getOverlay(false), Imgproc.COLOR_GRAY2BGRA);
        }

        if (!buffers.hasDetected()) {
            tiles = (tiles % 9) + 1;
        }
        final int tileHeight = (int) image.size().height / tiles;
        final int tileWidth = (int) image.size().width / tiles;

        // Split image into tiles and apply process on each image tile separately.
        for (int tileRow = 0; tileRow < tiles; tileRow++) {
            final int startRow = tileRow * tileHeight;
            int endRow;
            if (tileRow < tiles - 1) {
                endRow = (tileRow + 1) * tileHeight;
            } else {
                endRow = (int) image.size().height;
            }

            for (int tileCol = 0; tileCol < tiles; tileCol++) {
                final int startCol = tileCol * tileWidth;
                int endCol;
                if (tileCol < tiles - 1) {
                    endCol = (tileCol + 1) * tileWidth;
                } else {
                    endCol = (int) image.size().width;
                }

                final Mat tileMat = image.submat(startRow, endRow, startCol, endCol);
                Imgproc.threshold(tileMat, tileMat, 127, 255, Imgproc.THRESH_OTSU);
                tileMat.release();
            }
        }

        if (display == Display.threshold) {
            Imgproc.cvtColor(image, buffers.getOverlay(false), Imgproc.COLOR_GRAY2BGRA);
        }

        buffers.setImage(image);
    }

    @Override
    public void getSettings(List<DetectorSetting> settings) {
        settings.add(new DetectorSetting() {
            @Override
            public void nextValue() {
                display = display.next();
            }

            @Override
            public int getIcon() {
                switch (display) {
                case none:
                    return R.drawable.ic_image_24dp;
                case greyscale:
                    return R.drawable.ic_gradient_24dp;
                case threshold:
                    return R.drawable.ic_filter_b_and_w_24dp;
                }
                return 0;
            }

            @Override
            public int getText() {
                switch (display) {
                case none:
                    return R.string.draw_threshold_off;
                case greyscale:
                    return R.string.draw_threshold_greyscale;
                case threshold:
                    return R.string.draw_threshold_on;
                }
                return 0;
            }
        });
    }
}