add procImage module

This commit is contained in:
kekee000 2015-03-30 19:47:02 +08:00
parent d57febbf25
commit efb4fd4387
12 changed files with 415 additions and 12 deletions

View File

@ -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;
// }
}
}

View File

@ -91,7 +91,7 @@ define(
});
ctx.putImageData(imgData, 0, 0);
getBreakPoint(contours);
//getBreakPoint(contours);
var contours = fitImageContours(result, getOptions());

138
demo/js/procImage.js Normal file
View File

@ -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;
}
);

44
demo/procImage.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas查找关键点</title>
<script src="../dep/esl.js"></script>
<script src="../dep/jquery.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div>
<input id="upload-file" type="file">
灰度阈值:<input id="threshold-gray" type="range" min="0" max="255" value="200">
反转图像:<input id="threshold-reverse" type="checkbox">
二值算子:
<select id="threshold-fn">
<option value="">二值算子</option>
<option value="mean">基于灰度平均值的阈值</option>
<option value="minimum">基于谷底最小值的阈值</option>
<option value="intermodes">基于双峰平均值的阈值</option>
<option value="ostu">大津法</option>
<option value="isoData">ISODATA法</option>
</select>
</div>
<canvas id="canvas" width="800" height="800"></canvas>
<script>
require.config({
baseUrl: '../src',
paths: {
demo: '../demo/js',
}
});
define('jquery', $);
</script>
<script>require(['demo/procImage'])</script>
</body>
</html>

View File

@ -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;
}
);

View File

@ -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;
}
);

View File

@ -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;
}
);

View File

@ -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);
}

View File

@ -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;
}
);