今天在做网页的时候发现一个问题,在父标签中使用了overflow:hidden;时,如果子标签中有元素的position设置成relative的时候,在IE6和IE7中父元素的overflow对其将不起作用,在IE8、FF,Chrome中均正常显示如下代码:
<div style="height:100px; width:100px; background:#CCC; overflow:hidden;"> <div style="height:300px; width:90px; background:#999; position:relative;"></div> </div>
效果如下图:
解决方案:将父标签的position也设置成relative,代码如下:
<div style="height:100px; width:100px; background:#CCC; overflow:hidden; position:relative;"> <div style="height:300px; width:90px; background:#999; position:relative;"></div> </div>
效果如图所示:
效果如上图正常显示。
前言
上一篇文章,我们讲解了图像处理中的膨胀和腐蚀函数,这篇文章将做边缘梯度计算函数。直接摘自OpenCV 2.4+ C++ 边缘梯度计算。
图像的边缘
图像的边缘从数学上是如何表示的呢?
图像的边缘上,邻近的像素值应当显著地改变了。而在数学上,导数是表示改变快慢的一种方法。梯度值的大变预示着图像中内容的显著变化了。
用更加形象的图像来解释,假设我们有一张一维图形。下图中灰度值的“跃升”表示边缘的存在:
使用一阶微分求导我们可以更加清晰的看到边缘“跃升”的存在(这里显示为高峰值):
由此我们可以得出:边缘可以通过定位梯度值大于邻域的相素的方法找到。
近似梯度
比如内核为3时。
首先对x方向计算近似导数:
然后对y方向计算近似导数:
然后计算梯度:
当然你也可以写成:
函数实现
(__src && (__xorder ^ __yorder)) || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type === "CV_GRAY"){
var kernel1,
kernel2,
height = __src.row,
width = __src.col,
dst = __dst || new Mat(height, width, CV_16I, 1),
dstData = dst.data
size = __size || 3;
switch(size){
case 1:
size = 3;
case 3:
if(__xorder){
kernel = [-1, 0, 1,
-2, 0, 2,
-1, 0, 1
];
}else if(__yorder){
kernel = [-1, -2, -1,
0, 0, 0,
1, 2, 1
];
}
break;
case 5:
if(__xorder){
kernel = [-1, -2, 0, 2, 1,
-4, -8, 0, 8, 4,
-6,-12, 0,12, 6,
-4, -8, 0, 8, 4,
-1, -2, 0, 2, 1
];
}else if(__yorder){
kernel = [-1, -4, -6, -4, -1,
-2, -8,-12, -8, -2,
0, 0, 0, 0, 0,
2, 8, 12, 8, 2,
1, 4, 6, 4, 1
];
}
break;
default:
error(arguments.callee, UNSPPORT_SIZE/* {line} */);
}
GRAY216IC1Filter(__src, size, height, width, kernel, dstData, __borderType);
}else{
error(arguments.callee, UNSPPORT_DATA_TYPE/* {line} */);
}
return dst;
};
这里只提供了内核大小为3和5的Sobel算子,主要原因是7或以上的内核计算就比较慢了。
输出一个单通道的16位有符号整数矩阵。
var start = size >> 1;
var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType);
var mData = withBorderMat.data,
mWidth = withBorderMat.col;
var i, j, y, x, c;
var newValue, nowX, offsetY, offsetI;
for(i = height; i--;){
offsetI = i * width;
for(j = width; j--;){
newValue = 0;
for(y = size; y--;){
offsetY = (y + i) * mWidth;
for(x = size; x--;){
nowX = x + j;
newValue += (mData[offsetY + nowX] * kernel[y * size + x]);
}
}
dstData[j + offsetI] = newValue;
Express利用HTTP动作提供了有意义并富有表现力的URL映射API,例如我们可能想让用户帐号的URL看起来像/user/12的样子,下面的例子就能实现这样的路由,其中与占位标识符(本例为:id)相关的值可以被req.params获取到。
URL路径和参数看起来没有任何分别,真正的区别在于,将被哪个对象获取,例如:下面例子和对应的URL:http://..../user/12,user将匹配路径,12将匹配参数:id,它将被req.params对象获取到。
res.send('user ' + req.params.id);
});
上例中当我们访问/user/12时返回“user 12”。
注:app.get相当于在服务器注册了一个监听get请求事件的侦听器,当请求的URL满足第一个参数时,执行后面的回调函数,该过程是异步的。
路由是一个可以被内部编译成正则表达式的简单字符串,比如当/user/:id被编译后,被内部编译后的正则表达式字符串看起来会是下面的样子(简化后):
要实现复杂点的,我们可以传入正则表达式直接量,因为正则捕获组是匿名的因此我们可以通过req.params进行访问,第一个捕获组应该是req.params[0],第二个应该是req.params[1],以此类推。
res.send(req.params);
});
通过不同的url来测试我们定义的路由:
http://127.0.0.1:3000/users/any[
null,
null
]http://127.0.0.1:3000/users/12
[
"12",
null
]
http://127.0.0.1:3000/users/12..28[
"12",
"28"
]
下面是一些路由例子,以及与之相匹配的关联路径:
/user/12
"/users/:id?"
/users/5
/users
"/files/*"
/files/jquery.js
/files/javascripts/jquery.js
"/file/*.*"
/files/jquery.js
/files/javascripts/jquery.js
"/user/:id/:operation?"
/user/1
/user/1/edit
"/products.:format"
/products.json
/products.xml
"/products.:format?"
/products.json
/products.xml
/products
"/user/:id.:format?"
/user/12
/user/12.json
本文链接