diff --git a/demo/js/canvasFindBreakPoint.js b/demo/js/canvasFindBreakPoint.js index 1b95f19..2460110 100644 --- a/demo/js/canvasFindBreakPoint.js +++ b/demo/js/canvasFindBreakPoint.js @@ -66,12 +66,12 @@ define( putData[offset * 4 + 2] = 113; putData[offset * 4 + 3] = 255; } - else { - putData[offset * 4] = 255; - putData[offset * 4 + 1] = 255; - putData[offset * 4 + 2] = 255; - putData[offset * 4 + 3] = 255; - } + // else { + // putData[offset * 4] = 255; + // putData[offset * 4 + 1] = 255; + // putData[offset * 4 + 2] = 255; + // putData[offset * 4 + 3] = 255; + // } } } diff --git a/demo/js/fitImage.js b/demo/js/fitImage.js index a77a1fa..4d66055 100644 --- a/demo/js/fitImage.js +++ b/demo/js/fitImage.js @@ -91,7 +91,7 @@ define( }); ctx.putImageData(imgData, 0, 0); - getBreakPoint(contours); + //getBreakPoint(contours); var contours = fitImageContours(result, getOptions()); diff --git a/demo/js/procImage.js b/demo/js/procImage.js new file mode 100644 index 0000000..667767f --- /dev/null +++ b/demo/js/procImage.js @@ -0,0 +1,138 @@ +/** + * @file canvas读取图片 + * @author mengke01(kekee000@gmail.com) + */ + +define( + function (require) { + var grayImage = require('graphics/image/grayImage'); + var procImage = require('graphics/image/procImage'); + var binarizeImage = require('graphics/image/filter/binarize'); + var image2Values = require('graphics/image/image2Values'); + var findContours = require('graphics/image/findContours'); + var pathUtil = require('graphics/pathUtil'); + + var ctx = null; + var canvas = null; + var curImage = null; + + function getOptions() { + return { + threshold: $('#threshold-fn').val() ? $('#threshold-fn').val() : +$('#threshold-gray').val(), + reverse: !!$('#threshold-reverse').get(0).checked + } + } + + function onUpFileChange(e) { + var file = e.target.files[0]; + var reader = new FileReader(); + reader.onload = function(e) { + + var image = curImage = new Image(); + image.onload = function () { + getContours(image); + }; + + image.src = e.target.result; + } + + reader.onerror = function(e) { + console.error(e); + }; + + reader.readAsDataURL(file); + } + + function getContours(image) { + ctx.clearRect(0,0, canvas.width, canvas.height); + var width = image.width; + var height = image.height; + canvas.width = image.width; + canvas.height = image.height; + + ctx.drawImage(image, 0, 0, width, height); + var imgData = ctx.getImageData(0, 0, width, height); + + var grayData = procImage(imgData); + var putData = imgData.data; + var putGrayData = grayData.data; + + for (var y = 0; y < height; y ++) { + var line = width * y; + for (var x = 0; x < width; x++) { + var offset = line + x; + var gray = putGrayData[offset]; + putData[offset * 4] = gray; + putData[offset * 4 + 1] = gray; + putData[offset * 4 + 2] = gray; + putData[offset * 4 + 3] = 255; + + // if (result.data[offset]) { + // putData[offset * 4] = 208; + // putData[offset * 4 + 1] = 247; + // putData[offset * 4 + 2] = 113; + // putData[offset * 4 + 3] = 255; + // } + // else { + // putData[offset * 4] = 255; + // putData[offset * 4 + 1] = 255; + // putData[offset * 4 + 2] = 255; + // putData[offset * 4 + 3] = 255; + // } + } + } + + // var result = binarizeImage(grayData, getOptions().threshold); + // var contours = findContours(result); + + // contours.forEach(function (contour) { + // var flag = contour.flag; + // for (var i = 0, l = contour.length; i < l; i++) { + // var p = contour[i]; + // var offset = p.y * width + p.x; + // putData[offset * 4] = flag ? 100 : 255; + // putData[offset * 4 + 1] = 0; + // putData[offset * 4 + 2] = 0; + // putData[offset * 4 + 3] = 255; + // } + // }); + ctx.putImageData(imgData, 0, 0); + } + + function refresh() { + curImage && getContours(curImage, getOptions()); + } + + var entry = { + + /** + * 初始化 + */ + init: function () { + + document.getElementById('upload-file').addEventListener('change', onUpFileChange); + canvas = document.getElementById("canvas"); + ctx = canvas.getContext("2d"); + + $('#threshold-gray').on('change', function () { + $('#threshold-fn').val(''); + refresh(); + }); + + $('#threshold-fn').on('change', refresh); + $('#threshold-reverse').on('change', refresh); + + var img = new Image(); + img.onload = function () { + curImage = img; + refresh(); + } + img.src = '../test/rw1.jpg'; + } + }; + + entry.init(); + + return entry; + } +); diff --git a/demo/procImage.html b/demo/procImage.html new file mode 100644 index 0000000..66c26e1 --- /dev/null +++ b/demo/procImage.html @@ -0,0 +1,44 @@ + + + + + canvas查找关键点 + + + + + +
+ + 灰度阈值: + 反转图像: + 二值算子: + +
+ + + + + + diff --git a/src/graphics/image/binarizeImage.js b/src/graphics/image/filter/binarize.js similarity index 100% rename from src/graphics/image/binarizeImage.js rename to src/graphics/image/filter/binarize.js diff --git a/src/graphics/image/filter/brightness.js b/src/graphics/image/filter/brightness.js new file mode 100644 index 0000000..0e13282 --- /dev/null +++ b/src/graphics/image/filter/brightness.js @@ -0,0 +1,40 @@ +/** + * @file 亮度对比度计算 + * @author mengke01(kekee000@gmail.com) + */ + + +define( + function (require) { + + + /** + * 调节图像亮度对比度 + * + * @param {Object} imgData 图像数据 + * @param {string} brightness 亮度 -50 ~ 50 + * @param {number} contrast 对比度 -50 ~ 50 + * @return {Object} 调整后图像 + */ + function brightness(imgData, brightness, contrast) { + + brightness = brightness || 50; + contrast = contrast || 0; + + var data = imgData.data; + var b = brightness / 50; // -1 , 1 + var c = (brightness || 0) / 50; // -1 , 1 + var k = Math.tan((45 + 44 * c) * Math.PI / 180); + + for (var i = 0, l = data.length; i < l; i++) { + data[i] = Math.floor((data[i] - 127.5 * (1 - b)) * k + 127.5 * (1 + b)); + } + + return imgData; + } + + + + return brightness; + } +); diff --git a/src/graphics/image/filter/gaussBlur.js b/src/graphics/image/filter/gaussBlur.js new file mode 100644 index 0000000..4572e2a --- /dev/null +++ b/src/graphics/image/filter/gaussBlur.js @@ -0,0 +1,102 @@ +/** + * @file 高斯模糊 + * @author mengke01(kekee000@gmail.com) + * + * http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html + * @reference + * https://github.com/AlloyTeam/AlloyImage + */ + + +define( + function (require) { + + + function getGaussMatrix(radius, sigma) { + var gaussMatrix = []; + var gaussSum = 0; + var a = 1 / (2 * Math.PI * sigma * sigma); + var b = -1 / (2 * sigma * sigma); + var x; + var y; + var k; + + //生成高斯矩阵 + for (k = 0, x = -radius; x <= radius; x++) { + for (y = -radius; y <= radius; y++) { + var g = a * Math.exp(b * (x * x + y * y)); + gaussMatrix[k++] = g; + gaussSum += g; + } + } + + //归一化, 保证高斯矩阵的值在[0,1]之间 + for (k = 0, x = -radius; x <= radius; x++) { + for (y = -radius; y <= radius; y++) { + gaussMatrix[k++] /= gaussSum; + } + } + + return gaussMatrix; + } + + /** + * 灰度图像高斯模糊 + * + * @param {Object} imgData 图像数据 + * @param {number} radius 取样区域半径, 正数, 可选, 默认为 3.0 + * @param {number} sigma 标准方差, 可选, 默认取值为 radius / 3 + * + * @return {Object} + */ + function gaussBlur(imgData, radius, sigma) { + + radius = Math.floor(radius) || 1; + + var data = imgData.data; + var width = imgData.width; + var height = imgData.height; + var gaussMatrix = getGaussMatrix(radius, sigma || 1.5); + + var x; + var y; + var i; + var j; + var k; + var r; + var posX; + var posY; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + r = 0; + + // 计算高斯权值 + for (k = 0, i = -radius; i <= radius; i++) { + for (j = -radius; j <= radius; j++) { + posX = x + i; + + if (posX < 0 || posX >= width) { + posX = x - i; + } + + posY = y + j; + if (posY < 0 || posY >= height) { + posY = y - j; + } + + r += data[posX + posY * width] * gaussMatrix[k++]; + } + } + + data[x + y * width] = Math.floor(r); + } + } + + return imgData; + } + + + return gaussBlur; + } +); diff --git a/src/graphics/image/imageFilter.js b/src/graphics/image/filter/middle.js similarity index 100% rename from src/graphics/image/imageFilter.js rename to src/graphics/image/filter/middle.js diff --git a/src/graphics/image/filter/sharp.js b/src/graphics/image/filter/sharp.js new file mode 100644 index 0000000..ce8e111 --- /dev/null +++ b/src/graphics/image/filter/sharp.js @@ -0,0 +1,44 @@ +/** + * @file 图像锐化滤镜 + * @author mengke01(kekee000@gmail.com) + * + * @reference + * https://github.com/AlloyTeam/AlloyImage + */ + + +define( + function (require) { + + + /** + * 灰度图像锐化 + * @param {Object} imgData 图像数据 + * @param {number} lamta 锐化参数 + * @return {Object} 处理后图像 + */ + function sharp(imgData, lamta) { + lamta = lamta || 0.6; + + var width = imageData.width; + var height = imageData.height; + var data = imageData.data; + + var line = 0; + for (var y = 1; y < height; y++) { + line = y * width; + for (var x = 1; x < width; x++) { + var idx = x + line; + // 当前点减去 左侧三个像素点的平均值 + var delta = data[idx] - (data[idx - 1] + data[idx - width] + data[idx - width - 1]) / 3; + data[idx] = delta * lamta; + } + } + + return imgData; + + } + + return sharp; + } +); diff --git a/src/graphics/image/threshold.js b/src/graphics/image/filter/threshold.js similarity index 100% rename from src/graphics/image/threshold.js rename to src/graphics/image/filter/threshold.js diff --git a/src/graphics/image/image2Values.js b/src/graphics/image/image2Values.js index 85510fd..0cc6d4f 100644 --- a/src/graphics/image/image2Values.js +++ b/src/graphics/image/image2Values.js @@ -8,8 +8,7 @@ define( function (require) { var grayImage = require('./grayImage'); - var imageFilter = require('./imageFilter'); - var binarizeImage = require('./binarizeImage'); + var binarizeImage = require('./filter/binarize'); /** * 对图像进行二值化 @@ -23,10 +22,7 @@ define( */ function image2values(imageData, options) { options = options || {}; - imageData = grayImage(imageData, options.reverse); - - //imageData = imageFilter(imageData); return binarizeImage(imageData, options.threshold); } diff --git a/src/graphics/image/procImage.js b/src/graphics/image/procImage.js new file mode 100644 index 0000000..6c05480 --- /dev/null +++ b/src/graphics/image/procImage.js @@ -0,0 +1,39 @@ +/** + * @file 对图像进行预处理 + * @author mengke01(kekee000@gmail.com) + */ + + +define( + function (require) { + + + var grayImage = require('./grayImage'); + var binarizeImage = require('./filter/binarize'); + + var gaussBlur = require('./filter/gaussBlur'); + var brightness = require('./filter/brightness'); + + /** + * 对图像进行二值化 + * + * @param {Object} imageData 原始图像数据,rgba序列 + * @param {Array} imageData.data 数据数组 + * @param {number} imageData.width 宽度 + * @param {number} imageData.height 高度 + * + * @param {number} reverse 是否反转图像, 0~255 + */ + function procImage(imageData, options) { + options = options || {}; + + imageData = grayImage(imageData, options.reverse); + //imageData = gaussBlur(imageData); + + imageData = brightness(imageData, -30); + return imageData; + } + + return procImage; + } +);