Показать сообщение отдельно
  #1 (permalink)  
Старый 16.10.2013, 20:23
Аспирант
Посмотреть профиль Найти все сообщения от juser367
 
Регистрация: 16.10.2013
Сообщений: 36

Canvas что-то странное
Изображение не выводится полностью. Код прилагаю
var img = document.getElementsByTagName('img')[0];
// для начала представим изображение в виде массива оттенков серого
var pixels = grayscale(img);
var hist = histogram(pixels);
var threshold = otsu(hist, pixels.length); 

var cnv = document.createElement('canvas');
cnv.width = img.width;
cnv.height = img.height;
var ctx = cnv.getContext('2d');
var imageData = ctx.createImageData(img.width, img.height);
console.log(pixels.length + ', ' + imageData.data.length);
var i = 0;
var limit;
var index = 0;
while (i < pixels.length) {
    limit = i + img.width;
    while (i < limit) {
        for (var j = 0; j < 3; ++j)
            imageData.data[index++] = 255 * (pixels[i] > threshold);
        imageData.data[index++] = 255;
        ++i;
    }
}
ctx.putImageData(imageData, 0, 0);
document.body.appendChild(cnv);

function grayscale(img) {
    // используем типизированные массивы для оптимизации
    var ret = new Uint8Array(img.width * img.height);
    var cnv = document.createElement('canvas');
    var ctx = cnv.getContext('2d');
    ctx.drawImage(img, 0, 0);
    var pixels = ctx.getImageData(0, 0, img.width, img.height).data; 
    var red, green, blue;
    var index = 0;    
    for (var i = 0; i < pixels.length; i += 4) {
        red = pixels[i];
        green = pixels[i + 1];
        blue = pixels[i + 2]; 
        ret[index] = Math.round(0.3 * red + 0.59 * green + 0.11 * blue);
        ++index;
    }
    return ret;
}

function histogram(data) {
    var ret = new Uint32Array(256);
    for (var i = 0; i < data.length; ++i)
        ++ret[data[i]];
    return ret;
}

// [url]http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html[/url]
function otsu(histogram, total) {
    var sum = 0;
    for (var i = 1; i < 256; ++i)
        sum += i * histogram[i];
    var sumB = 0;
    var wB = 0;
    var wF = 0;
    var mB;
    var mF;
    var max = 0;
    var between;
    var threshold = 0;
    for (var i = 0; i < 256; ++i) {
        wB += histogram[i];
        if (wB == 0)
            continue;
        wF = total - wB;
        if (wF == 0)
            break;
        sumB += i * histogram[i];
        mB = sumB / wB;
        mF = (sum - sumB) / wF;
        between = wB * wF * Math.pow(mB - mF, 2);
        if (between > max) {
            max = between;
            threshold = i;
        }
    }
    return threshold;
}

Скрин
http://cdn.sstatic.net/stackoverflow...lyglot-404.png
Ответить с цитированием