Алгоритм чтения изображения в виде строк (затем получить результат из них)?

Есть ли алгоритм для получения штрихов строки изображения (игнорировать кривые, круги и т.д., все будет рассматриваться как линии, но все же похожие на векторы), из их пикселей? Затем получите результат из них, например, Array?

Вот как это было бы в основном работать над чтением

Basic read

Таким образом, каждая строка пикселя будет считана как 1 горизонтальная линия, и я тоже хотел бы обрабатывать вертикальные линии; но если есть сплошная жирная линия, которая занимает более 1 строки

круглая жирная линия

это будет считаться одной строкой. Его ширина линии равна той же высоте пикселей, что и у нее.

Например, предположим, что у нас есть массив, содержащий строки пикселей в (красный, зеленый, синий, альфа-формат) (JavaScript):

/* formatted ImageData().data */
[
    new Uint8Array([
        /* first pixel */
        255, 0, 0, 255,
        /* second pixel */
        255, 0, 0, 255
    ]),

    new Uint8Array([
        /* first pixel */
        0, 0, 0, 0,
        /* second pixel */
        0, 0, 0, 0
    ])
]

Это будут данные изображения 2x2px с прямой горизонтальной красной линией. Итак, из этого массива я хочу получить массив, содержащий данные строк, например:

[
    // x, y: start point
    // tx, ty: end point
    // w: line width

    // the straight horizontal red line of 1 pixel
    { x: 0, y: 0, tx: 2, ty: 0, w: 1, rgba: [255, 0, 0, 255] }
]

Примечание. Я хотел бы обработать сглаживание.

Это моя функция для чтения пикселей в вышеуказанном формате:

var getImagePixels = function(img){
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    canvas.width = img.width;
    canvas.height = img.height;

    ctx.drawImage(img, 0, 0);

    var imgData = ctx.getImageData(0, 0, img.width, img.height).data;
    var nImgData = [];
    var offWidth = img.width * 4;

    var dataRow = (nImgData[0] = new Uint8Array(offWidth));

    for (var b = 0, i = 0; b++ < img.height;) {
        nImgData[b] = new Uint8Array(offWidth);

        for (var arrI = 0, len = i + offWidth; i < len; i += 4, arrI += 4) {
            nImgData[b][arrI] = imgData[i];
            nImgData[b][arrI + 1] = imgData[i + 1];
            nImgData[b][arrI + 2] = imgData[i + 2];
            nImgData[b][arrI + 3] = imgData[i + 3];
        }
    }

    return nImgData;
};

Ответы

Ответ 1

Вы можете найти все строки, используя Преобразование Hough. Он найдет только линии, без кривых или кругов. Возможно, вам придется выполнять поиск границ перед поиском строк. Вот пример: введите описание изображения здесь введите описание изображения здесь

Здесь вы можете найти opencv-пример реализации.

Ответ 2

У меня был аналогичный вопрос обработки изображений один раз, вы можете прочитать его здесь. Но вы можете в принципе принять ту же идею за все, что вы хотите сделать с изображением.

Основные данные можно увидеть следующим образом:

var img = new Image,
    w = canvas.width,
    h = canvas.height,
    ctx = canvas.getContext('2d');

img.onload = imgprocess;
img.src = 'some.png';

function imgprocess() { 
    ctx.drawImage(this, 0, 0, w, h);

    var idata = ctx.getImageData(0, 0, w, h),
    buffer = idata.data,
    buffer32 = new Uint32Array(buffer.buffer),
    x, y,
    x1 = w, y1 = h, x2 = 0, y2 = 0;

    //You now have properties of the image from the canvas data. You will need to write your own loops to detect which pixels etc... See the example in the link for some ideas. 
}

UPDATE:

Рабочий пример поиска цветовых данных;

var canvas = document.getElementById('canvas');
var canvasWidth  = canvas.width;
var canvasHeight = canvas.height;
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);

var buf = new ArrayBuffer(imageData.data.length);
var buf8 = new Uint8ClampedArray(buf);
var data = new Uint32Array(buf);

for (var y = 0; y < canvasHeight; ++y) {
    for (var x = 0; x < canvasWidth; ++x) {
        var value = x * y & 0xff;

        data[y * canvasWidth + x] =
            (255   << 24) |    // alpha
            (value << 16) |    // blue
            (value <<  8) |    // green
             value;            // red
    }
}

Далее можно увидеть здесь

Автор выше описывает пиксельные и линейные данные:

Свойство ImageData.data, на которое ссылаются данные переменной, представляет собой одномерный массив целых чисел, каждый из которых находится в диапазоне 0..255. ImageData.data размещается в повторяющейся последовательности, так что каждый элемент относится к отдельному каналу. Эта повторяющаяся последовательность выглядит следующим образом:

data[0]  = red channel of first pixel on first row
data[1]  = green channel of first pixel on first row
data[2]  = blue channel of first pixel on first row
data[3]  = alpha channel of first pixel on first row

data[4]  = red channel of second pixel on first row
data[5]  = green channel of second pixel on first row
data[6]  = blue channel of second pixel on first row
data[7]  = alpha channel of second pixel on first row

data[8]  = red channel of third pixel on first row
data[9]  = green channel of third pixel on first row
data[10] = blue channel of third pixel on first row
data[11] = alpha channel of third pixel on first row