[Canvas绘图] 第28节 分块治图

来源:互联网 发布:async.js 157 编辑:程序博客网 时间:2024/06/05 15:55
本节目标:
(1) 我忽然间想到一个分区域读图取轮廓的方法,想了一夜,觉得要实现看看效果怎样。


实现步骤:

(1)首先确定了中心思想,对于一张图的轮廓,必然是像素变化比较剧烈的点,这个先前已经有了

简易的判定。但是以疥是按行列扫描判定,这次我决定按区块扫描判定。按区块的目的是因为如果区块

够小,可以把它当作一个单元来处理,于是我定义了这样一个结构:

/*** @usage   分块治图取轮廓* @author  mw* @date    2015年12月20日  星期日  10:46:21 * @param* @return**/function Nexus() {//方格大小范围,比如2*2, 10*10, 100*100个象素this.range = 100;//方格序数this.xth = 0;this.yth = 0;//方格开始和结束的x,y象素点坐标this.xBeg = 0;this.xEnd = 0;this.yBeg = 0;this.yEnd = 0;//候选点的x, y极值this.xMax = 0;this.xMin = 0;this.yMax = 0;this.yMin = 0;//候选点个数和比例this.count = 0;this.percent = 0;//候选点的x, y总值this.xTotal = 0;this.yTotal = 0;//候选点族的中心this.xCenter = 0;this.yCenter = 0;//候选点族的半径区域this.r = 0;//需要传入参数xth, yth, rangethis.init = function(xth, yth, range) {this.xth = xth;this.yth = yth;this.range = range;//方格开始和结束的x,y象素点坐标this.xBeg = 0 + this.xth * this.range;this.xEnd = 0 + (this.xth+1) * this.range;this.yBeg = 0 + this.yth * this.range;this.yEnd = 0 + (this.yth+1) * this.range;};//传入7个参数this.calc = function(count, xTotal, yTotal, xMax, yMax, xMin, yMin) {this.count = count;this.xTotal = xTotal;this.yTotal = yTotal;this.xMax = xMax;this.xMin = xMin;this.yMax = yMax;this.yMin = yMin;this.percent = this.count / (this.range * this.range);//候选点族的中心this.xCenter = this.count==0 ? (this.xBeg+this.xEnd)/2 : this.xTotal / this.count;this.yCenter = this.count==0 ? (this.yBeg+this.yEnd)/2 : this.yTotal / this.count;//候选点族的半径区域this.r = Math.min(Math.abs(this.xMax - this.xCenter),Math.abs(this.xMin - this.xCenter),Math.abs(this.yMax - this.yCenter),Math.abs(this.yMin - this.yCenter),this.range);};}

(2) 这次我要用的就是中心点,其它的可以先不管,于是写了读图函数

function step1() {var arr = new Array();var pointInfo="$picDataArray = [";//图片var image = new Image();image.src = "./1.jpg";//只处理这100*100个象素var width = 600;var height = 400;//格子大小,行和列共有多少格var range = 8;var rows = height / range;var cols = width / range;//确定范围var xBeg, xEnd, yBeg, yEnd;//待计算参数var count, xTotal, yTotal, xMin, yMin, xMax, yMax;var gap = 20;image.onload = function() {plot.drawImage(image);var imagedata = plot.getImageData(0, 0, width, height);//计算for (var i = 0; i < cols; i++) {for (var j = 0; j < rows; j++) {var nexus = new Nexus();nexus.init(i, j, range);//确定范围xBeg = nexus.xBeg;xEnd = nexus.xEnd;yBeg = nexus.yBeg;yEnd = nexus.yEnd;//待计算参数xMin = nexus.xMin;xMax = nexus.xMax;yMin = nexus.yMin;yMax = nexus.yMax;count = 0;xTotal = 0;yTotal = 0;//水平方向找差异for (var col = xBeg+1; col < xEnd; col++) {for (var row = yBeg; row<yEnd; row++) {//pos最小为1pos =row * width + col;R0 = imagedata.data[4 * (pos-1)];R1 = imagedata.data[4 * pos];G0 = imagedata.data[4 * (pos-1)+1];G1 = imagedata.data[4 * pos+1];B0 = imagedata.data[4 * (pos-1)+2]B1 = imagedata.data[4 * pos + 2]//简单容差判断if (Math.abs(R1-R0) > gap || Math.abs(G1-G0)>gap || Math.abs(B1-B0)>gap){count++;xTotal += col;yTotal += row;if (xMin > col) xMin = col;if (xMax < col) xMax = col;if (yMin > row) yMin = row;if (yMax < row) yMax = row;}}}//垂直方向找差异for (var col = xBeg; col < xEnd; col++) {for (var row = yBeg+1; row<yEnd; row++) {//pos最小为第二行pos =row * width  + col;R0 = imagedata.data[4 * (pos-width)];R1 = imagedata.data[4 * pos];G0 = imagedata.data[4 * (pos-width)+1];G1 = imagedata.data[4 * pos+1];B0 = imagedata.data[4 * (pos-width)+2];B1 = imagedata.data[4 * pos + 2];//简单容差判断if (Math.abs(R1-R0) > gap || Math.abs(G1-G0)>gap || Math.abs(B1-B0)>gap) {count++;xTotal += col;yTotal += row;if (xMin > col) xMin = col;if (xMax < col) xMax = col;if (yMin > row) yMin = row;if (yMax < row) yMax = row;}}}nexus.calc(count, xTotal, yTotal, xMax, yMax, xMin, yMin);arr.push(nexus);}}arr.sort(function(a, b) {if (a[1] < b[1]) return -1;else if (a[1] > b[1]) {return 1;}else {if (a[0] < b[0]) return -1;else if (a[0] > b[0]) return 1;else return 0;}return 1;});var nexus = new Nexus();for (var i = 0; i < arr.length; i++) {nexus = arr[i];if (nexus.percent > 0.01 && nexus.percent < 0.9) {pointInfo += '[' + nexus.yth + ', ' + nexus.xth + ',' +nexus.xCenter.toFixed(0) + ', ' + nexus.yCenter.toFixed(0)+'], ';}if (nexus.percent > 0.01 && nexus.percent < 0.9) {fillCircle(nexus.xCenter, nexus.yCenter, 4);}else {fillCircle(nexus.xCenter, nexus.yCenter, 1);}}pointInfo += '];';var pointInfoNode = document.createTextNode(pointInfo);document.body.appendChild(pointInfoNode);}}


(3)  然后我又写了一个连线函数,和一个简单的处理函数。

//连线function step2(array) {//array数组中的每个单元都是有4个参数的,分别是yth, xth, xCenter, yCentervar len = array.length;for (var i = 0; i < len; i++) {fillCircle(array[i][2], array[i][3], 2);for (var j = i; j < len; j++) {if (Math.abs(array[i][0] - array[j][0]) +  Math.abs(array[i][1] - array[j][1]) <= 1 ) {plot.moveTo(array[i][2], array[i][3]).lineTo(array[j][2], array[j][3]).stroke();}}}}function picData() {plot.init();setPreference();//step1();step2($picDataArray);}


(4) 都准备齐全了。就该来看结果了。

第一个处理的样本是一个很简单的图:

接着是这样一张风景:




可是这个风景实在是超出了这些代码的处理能力了。以下是若干的尝试。


得出


继续


得出


继续


得出


还有这种


虽然看上去有点意思,但考虑到目标在那,这差距实在太大。看来处理风景是不行的,换个简单点的


得到


这个还算可以

然后我想到,这好像是文字的勾描啊,那处理文字怎样呢?


好像线条连的不好,把线条去掉看看。


有些地方还是有缺失。

接着我想拿个卡通图来试一下。


处理后


来看看


加线条


本节到此结束。


0 0
原创粉丝点击