首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用boofcv提取象形文字?

如何使用boofcv提取象形文字?
EN

Stack Overflow用户
提问于 2015-11-29 19:36:40
回答 1查看 640关注 0票数 2

我在将象形文字提取成更可处理的格式时遇到了问题,因为现在我得到了这样的信息:

当前解决方案的一部分来自BoofCV ImageTresholding示例。此解决方案的代码如下:

代码语言:javascript
复制
import georegression.metric.UtilAngle;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.IOException;

import boofcv.alg.color.ColorHsv;
import boofcv.alg.filter.binary.BinaryImageOps;
import boofcv.alg.filter.binary.GThresholdImageOps;
import boofcv.alg.filter.binary.ThresholdImageOps;
import boofcv.gui.ListDisplayPanel;
import boofcv.gui.binary.VisualizeBinaryData;
import boofcv.gui.image.ImagePanel;
import boofcv.gui.image.ShowImages;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.io.image.UtilImageIO;
import boofcv.struct.image.ImageFloat32;
import boofcv.struct.image.ImageUInt8;
import boofcv.struct.image.MultiSpectral;

public class Binaryzation {
    static double splitFraction = 0.05;
    static double minimumSideFraction = 0.1;

    static ListDisplayPanel gui = new ListDisplayPanel();

    public static void printClickedColor(final BufferedImage image) {
        ImagePanel gui = new ImagePanel(image);
        gui.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                float[] color = new float[3];
                int rgb = image.getRGB(e.getX(), e.getY());
                ColorHsv.rgbToHsv((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF,
                        rgb & 0xFF, color);
                System.out.println("H = " + color[0] + " S = " + color[1]
                        + " V = " + color[2]);
                try {
                    showSelectedColor("Selected", image, color[0], color[1]);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });

        ShowImages.showWindow(gui, "Color Selector");
    }

    public static void showSelectedColor(String name, BufferedImage image,
            float hue, float saturation) throws IOException {

        ImageUInt8 binary = binaryTreshold(name, image, hue, saturation);
        // MAGIC HAPPENDS -removing small objects
        ImageUInt8 filtered = BinaryImageOps.erode4(binary, 1, null);
        filtered = BinaryImageOps.dilate8(filtered, 1, null);
        filtered = BinaryImageOps.removePointNoise(filtered, filtered);
        ShowImages.showWindow(filtered, "Binary " + name);
        BufferedImage visualFiltered1 = VisualizeBinaryData.renderBinary(
                filtered, true, null);
        ShowImages.showWindow(visualFiltered1, "Mask");
        BufferedImage visualFiltered12 = Fill.fill(visualFiltered1);
        ShowImages.showWindow(visualFiltered12, "Filled Mask");

    ImageUInt8 mask = ConvertBufferedImage.convertFromSingle(
            visualFiltered12, null, ImageUInt8.class);

    ImageUInt8 wynik = new ImageUInt8(mask.width, mask.height);

    //subtraction of images: wynik=mask-filtered;
    int min = 0;
    int max = 1;
    for (int i = 0; i < mask.height; i++) {
        // System.out.println("i=" + i);
        for (int j = 0; j < mask.width; j++) {
            // System.out.println("j=" + j);
            if (filtered.get(j, i) < min)
                min = filtered.get(j, i);
            if (filtered.get(j, i) > max)
                max = filtered.get(j, i);

            int filtInt = filtered.get(j, i);
            if (filtInt >= 1)
                filtInt = 1;
            else if (filtInt < 1)
                filtInt = 0;

            int maskInt = mask.get(j, i);
            if (maskInt >= 1)
                maskInt = 0;
            else if (maskInt < 1)
                maskInt = 1;

            int diff = maskInt - filtInt;
            if (diff == 1) {
                diff = 255;
                wynik.set(j, i, diff);
            } else if (diff == 0) {
                diff = 0;
                wynik.set(j, i, diff);
            } else {
                diff = 255;
                wynik.set(j, i, diff);

            }

        }
    }
    ShowImages.showWindow(wynik, "Wynik=Mask-Filtered");
    wynik = BinaryImageOps.erode4(wynik, 1, null);
    wynik = BinaryImageOps.dilate8(wynik, 1, null);
    wynik = BinaryImageOps.removePointNoise(wynik, wynik);
     UtilImageIO.saveImage(wynik, "C:/dev/zdjeciaTestowe/wynik.jpg");
    ShowImages.showWindow(wynik, "Wynik=Mask-Filtered After noise remove");

}

    private static ImageUInt8 binaryTreshold(String name, BufferedImage image,
            float hue, float saturation) throws IOException {
        MultiSpectral<ImageFloat32> input = ConvertBufferedImage
                .convertFromMulti(image, null, true, ImageFloat32.class);
        MultiSpectral<ImageFloat32> hsv = input.createSameShape();

        // Convert into HSV
        ColorHsv.rgbToHsv_F32(input, hsv);

        // Euclidean distance squared threshold for deciding which pixels are
        // members of the selected set
        float maxDist2 = 0.4f * 0.4f;

        // Extract hue and saturation bands which are independent of intensity
        ImageFloat32 H = hsv.getBand(0);
        ImageFloat32 S = hsv.getBand(1);

        // Adjust the relative importance of Hue and Saturation.
        // Hue has a range of 0 to 2*PI and Saturation from 0 to 1.
        float adjustUnits = (float) (Math.PI / 2.0);

        // step through each pixel and mark how close it is to the selected
        // color
        BufferedImage output = new BufferedImage(input.width, input.height,
                BufferedImage.TYPE_INT_RGB);
        for (int y = 0; y < hsv.height; y++) {
            for (int x = 0; x < hsv.width; x++) {
                // Hue is an angle in radians, so simple subtraction doesn't
                // work
                float dh = UtilAngle.dist(H.unsafe_get(x, y), hue);
                float ds = (S.unsafe_get(x, y) - saturation) * adjustUnits;

                // this distance measure is a bit naive, but good enough for to
                // demonstrate the concept
                float dist2 = dh * dh + ds * ds;
                if (dist2 <= maxDist2) {
                    System.out.println(image.getRGB(x, y));
                    output.setRGB(x, y, image.getRGB(x, y));
                }
            }
        }
        ImageFloat32 output1 = ConvertBufferedImage.convertFromSingle(output,
                null, ImageFloat32.class);
        ImageUInt8 binary = new ImageUInt8(input.width, input.height);

        double threshold = GThresholdImageOps.computeOtsu(output1, 0, 255);
        // Apply the threshold to create a binary image
        ThresholdImageOps.threshold(output1, binary, (float) threshold, true);

        return binary;
    }

    public static void main(String args[]) throws IOException {
        BufferedImage image = UtilImageIO
                .loadImage("C:/dev/zdjeciaTestowe/images.jpg");

        // Let the user select a color
        printClickedColor(image);
        // Display pre-selected colors
        showSelectedColor("Yellow", image, 1f, 1f);

    }
}
代码语言:javascript
复制
import java.awt.image.BufferedImage;
import boofcv.struct.image.ImageUInt8;

public class Fill {
    private static final int BLACK = -16777216;
    private static final int WHITE = -1;

    /**
     * @param input Buffered image
     * @return image with filled holes
     */
    public static BufferedImage fill(BufferedImage input) {
        int width = input.getWidth();
        int height = input.getHeight();
        BufferedImage output=new BufferedImage(width, height, input.getType());
        for (int i = 0; i < height; i++) {
            // System.out.println("i=" + i);
            for (int j = 0; j < width; j++) {
                // System.out.println("j=" + j);
                if (input.getRGB(j, i) == WHITE) {
                    output.setRGB(j, i, WHITE);
                } else if (isPreviusWhite(j, i, input)
                        && isAnotherWhiteInLine(j, i, input)) {
                    output.setRGB(j, i, WHITE);
                }
            }
        }
        return output;
    }

    private static boolean isPreviusWhite(int i, int i2, BufferedImage input) {
        boolean condition = false;
        while (1 < i2) {
            if (input.getRGB(i, i2) == WHITE)
                return true;
            i2--;
        }
        return condition;
    }

    private static boolean isAnotherWhiteInLine(int j, int i,
            BufferedImage input) {
        boolean condition = false;
        while (j < input.getWidth()) {
            if (input.getRGB(j, i) == WHITE)
                return true;
            j++;
        }
        return condition;
    }
}

我知道如何提取符号上的象形文字,我从填充的面罩中减去面罩,但有问题获得一些可处理的结果,因为在最后,我有一幅灰度图像,而不是二值图像(或者像在boofCV ImageUInt8中那样)。

如何正确地以ImageUInt8格式减去两幅图像,以便结果也是ImageUInt8

今天,我写了这个算法的更多部分,现在我想问的问题更清楚了。这里添加了代码(图像的//减法部分:wynik=掩码过滤;)和2幅附加图片作为处理的产物。

问题是去噪后的最后一幅图像是纯黑的,没有任何信息。如何正确转换图像以获得可处理的内容??我做错什么了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-05 20:19:16

我已经找到了解决我的问题的最后一张图片“wynik=蒙皮过滤后,噪音去除”有一个象形文字,但差的甜菜水飞蓟灰阶很低,很难看到如此解决问题的人正在添加: GrayImageOps.stretch(wynik,125,125,255,wynik);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33987135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档