OpenLayers: Zoom multiple layers to best common extent? - openlayers-3

Is there an easy way (other than getting layer extents separately and doing the calculation) to group the layers and zoom to the extent that is best for displaying shapes on all of the grouped layers?

Solution:
bounds = #get('siblingsLayer').getDataExtent()
bounds.extend(#get('vectorLayer').getDataExtent())
bounds.extend(#get('parentLayer').getDataExtent())
#get('map').zoomToExtent(bounds)

This one worked for me.
Code:
var allLayers = map.getLayers();
var length = allLayers.getLength();
var layerArray = ['Layer1', 'Layer2', ..., 'LayerN'];
var extent = ol.extent.createEmpty();
for (var i = 0; i < length; i++) {
var existingLayer = allLayers.item(i);
for (var j = 0; j < layerArray.length; j++) {
if (existingLayer.get('title') == layerArray[j]) {
ol.extent.extend(extent,existingLayer.getSource().getExtent());
}
}
}
map.getView().fit(extent, map.getSize());
Example:
I have added two layers and pointed to one layer among them.
After calling the API, my view updated and focused to both the layers:

Related

Why the initialization of weights in darknet?

there!
I am studying Mr. Redmon's darknet code from https://github.com/pjreddie/darknet
I found the initialization of weights of a connected layer is like below:
// file: src/connected_layer.c
// function: make_connected_layer
float scale = sqrt(2./inputs);
for(i = 0; i < outputs*inputs; ++i){
l.weights[i] = scale*rand_uniform(-1, 1);
}
and the initialization of weights of a convolutional layer is like below:
// file: src/convolutional_layer.c
// function: make_convolutional_layer
float scale = sqrt(2./(size*size*c/l.groups));
for(i = 0; i < l.nweights; ++i) {
l.weights[i] = scale*rand_normal();
}
Could you tell me what the principle is behind these code, please? Links to resources such as related papers are also OK.
Thank you a lot!

OpenCV - iterate over each blob in a binary image and use it as mask

I have a binary image and a color image of the same size. I need to iterate each blob (white pixel blocks) of the binary image and use it as a mask and find the mean color of this blob region from the color image.
I have tried:
HierarchyIndex[] hierarchy;
Point[][] contours;
binaryImage.FindContours(out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone);
using (Mat mask = Mat.Zeros(matColor.Size(), MatType.CV_8UC1))
foreach (var bl in contours)
if (Cv2.ContourArea(bl) > 5)
{
mask.DrawContour(bl, Scalar.White, -1);
Rect rect = Cv2.BoundingRect(bl);
Scalar mean = Cv2.Mean(colorImage[rect], mask[rect]);
mask.DrawContour(bl, Scalar.Black, -1);
}
which works for the blobs not having holes. However in my case I have many blob regions having huge holes that affects the mean calculation.
I couldn't figure it out how to solve it using the hierarchy info; or with another approach.
(My code is for OpenCVSharp but answer in any other wrapper or language is wellcome.)
Edit: I've added an example image. The traffic signs part is the problem.
Actually I think I have solved this problem with this method:
using PLine = List<Point>;
using Shape = List<List<Point>>;
internal static IEnumerable<Tuple<PLine, Shape>> FindContoursWithHoles(this Mat mat)
{
Point[][] contours;
HierarchyIndex[] hierarchy;
mat.FindContours(out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
Dictionary<int, bool> dic = new Dictionary<int, bool>();
for (int i = 0; i < contours.Length; i++)
if (hierarchy[i].Parent < 0)
dic[i] = true;
bool ok = false;
while (!ok)
{
ok = true;
for (int i = 0; i < contours.Length; i++)
if (dic.ContainsKey(i))
{
bool isParent = dic[i];
var hi = hierarchy[i];
if (hi.Parent >= 0) dic[hi.Parent] = (!isParent);
if (hi.Child >= 0) dic[hi.Child] = (!isParent);
while (hi.Next >= 0)
{
dic[hi.Next] = isParent;
hi = hierarchy[hi.Next];
if (hi.Parent >= 0) dic[hi.Parent] = (!isParent);
if (hi.Child >= 0) dic[hi.Child] = (!isParent);
}
hi = hierarchy[i];
while (hi.Previous >= 0)
{
dic[hi.Previous] = isParent;
hi = hierarchy[hi.Previous];
if (hi.Parent >= 0) dic[hi.Parent] = (!isParent);
if (hi.Child >= 0) dic[hi.Child] = (!isParent);
}
}
else
ok = false;
}
foreach (int i in dic.Keys.Where(a => dic[a]))
{
PLine pl = contours[i].ToList();
Shape childs = new Shape();
var hiParent = hierarchy[i];
if (hiParent.Child >= 0)
{
childs.Add(contours[hiParent.Child].ToList());
var hi = hierarchy[hiParent.Child];
while (hi.Next >= 0)
{
childs.Add(contours[hi.Next].ToList());
hi = hierarchy[hi.Next];
}
hi = hierarchy[hiParent.Child];
while (hi.Previous >= 0)
{
childs.Add(contours[hi.Previous].ToList());
hi = hierarchy[hi.Previous];
}
}
yield return Tuple.Create(pl, childs);
}
}
By drawing the holes as black, we can use each blob as a single mask:
var blobContours = blobs.FindContoursWithHoles().ToList();
using (Mat mask = Mat.Zeros(mat0.Size(), MatType.CV_8UC1))
for (int i = 0; i < blobContours.Count; i++)
{
var tu = blobContours[i];
var bl = tu.Item1;
if (Cv2.ContourArea(bl) > 100)
{
mask.DrawContour(bl, Scalar.White, -1);
foreach (var child in tu.Item2)
mask.DrawContour(child, Scalar.Black, -1);
Rect rect = Cv2.BoundingRect(bl);
Scalar mean = Cv2.Mean(mat0[rect], mask[rect]);
}
}
I think there should be an easier way.
And yet there is another problem. In some cases, an individual red part of the sign (which is a seperate white blob) does not found as a parent outside circle and a child inside circle, but a large parent contour outside with two circles as children (ie. hole inside another hole, makes a seperate blob which is not found as a parent). Yes it is hierarchically correct but does not help me. I hope I could make my self clear, sorry for my English.
#Miki thank you very much. I was able to achieve what I want using ConnectedComponents. Its simple and fast:
var cc = Cv2.ConnectedComponentsEx(binaryImage, PixelConnectivity.Connectivity8);
foreach (var bl in cc.Blobs)
using (Mat mask = new Mat())
{
cc.FilterByBlob(binaryImage, mask, bl);
Rect rect = bl.Rect;
Scalar mean = Cv2.Mean(colorImage[rect], mask[rect]);
}

How can I detect the number of lit faces on a mesh?

I have a number of objects arranged in a THREE.scene, and I want to calculate or retrieve a relative value indicating how much light each object is receiving from a single PointLight source. Simplified example:
With the light positioned at the camera, Block 1's value might be 0.50 since 3 of 6 faces are completely exposed, while 2 is ~0.33 and 3 is ~1.67.
I could probably do this the hard way by drawing a ray from the light toward the center of each face and looking at the intersects, but I'm assuming it's possible to directly retrieve the light level of each face.
This code takes the object's global matrix in consideration.
var amount = 0;
var rotationMatrix = new THREE.Matrix4();
var vector = new THREE.Vector3();
var centroid = new THREE.Vector3();
var normal = new THREE.Vector3();
for ( var i = 0; i < objects.length; i ++ ) {
var object = objects[ i ];
rotationMatrix.extractRotation( object.matrixWorld );
for ( var j = 0; j < object.geometry.faces.length; j ++ ) {
var face = object.geometry.faces[ j ];
centroid.copy( face.centroid );
object.matrixWorld.multiplyVector3( centroid );
normal.copy( face.normal );
rotationMatrix.multiplyVector3( normal );
vector.sub( light.position, centroid ).normalize();
if ( normal.dot( vector ) > 0 ) amount ++;
}
}
I think something like this should do the trick.
var amount = 0;
var faces = mesh.geometry.faces;
for ( var i = 0; i < geometry.faces.length; i ++ ) {
if ( geometry.faces[ i ].normal.dot( light.position ) > 0 ) amount ++;
}
(Warning: Brute force method!)
I'm including this for reference since it's what I'm currently using to meet all of the requirements described in the question. This function considers a face unlit if its center is not directly visible from the light's position.
I have no rotation matrix to consider for my application.
function getLightLevel(obj) {
/* Return percentage of obj.geometry faces exposed to light */
var litCount = 0;
var faces = obj.geometry.faces;
var faceCount = faces.length;
var direction = new THREE.Vector3();
var centroid = new THREE.Vector3();
for (var i=0; i < faceCount; i++) {
// Test only light-facing faces (from mrdoob's first answer).
if (faces[i].normal.dot(light.position) > 0) {
centroid.add(obj.position, faces[i].centroid);
direction.sub(centroid, light.position).normalize();
// Exclude face if centroid is obscured by another object.
var ray = new THREE.Ray(light.position, direction);
var intersects = ray.intersectObjects(objects);
if (intersects.length > 0 && intersects[0].face === faces[i]) {
litCount ++;
}
}
}
return litCount / faceCount;
}

Actionscript randomly distribute objects on stage

I'm trying to distribute 3 objects randomly on my stage but it's not working. My movie is 800x800.
function makeRock():void{
var tempRock:MovieClip;
for(var i:Number = 1; i < 3; i++){
tempRock = new Rock();
tempRock.x = Math.round(800);
tempRock.y = Math.round(-800);
addChild(tempRock);
}
}
What am I doing wrong?
Replace Math.round(800); with Math.random()*800;
function makeRock():void
{
var tempRock:MovieClip;
var i:uint = 0;
for(i; i < 3; i++)
{
tempRock = new Rock();
tempRock.x = Math.random()*800;
tempRock.y = Math.random()*800;
addChild(tempRock);
}
}
Math.round(800) is just returning 800.
Math.random() returns a random number between 0 and 1, which you can multiply by 800 to get a random result of 0-800. A good note to make is that Math.random() never actually returns 1.0. Just everything from 0 up to 1.
Further reading:
As a side note: this makes it simple to return a random element from an array; because you're never getting 1 you can cast the result of Math.random()*array.length to uint() and always be within the boundaries of the array length.
eg.
var ar:Array = [1,2,"hello",4,5,6,7,8,9,0];
var randomElement:Object = ar[uint(Math.random()*ar.length)];
trace(randomElement);

Histogram Smoothing

I have a probably pretty simple question but I am still not sure!
Actually I only want to smooth a histogram, and I am not sure which of the following to methods is correct. Would I do it like this:
vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;
vector<double> tmpVect(histogram->size());
for (unsigned int i = 0; i < histogram->size(); i++)
tmpVect[i] = (*histogram)[i];
for (int bin = 1; bin < histogram->size()-1; bin++) {
double smoothedValue = 0;
for (int i = 0; i < mask.size(); i++) {
smoothedValue += tmpVect[bin-1+i]*mask[i];
}
(*histogram)[bin] = smoothedValue;
}
Or would you usually do it like this?:
vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;
for (int bin = 1; bin < histogram->size()-1; bin++) {
double smoothedValue = 0;
for (int i = 0; i < mask.size(); i++) {
smoothedValue += (*histogram)[bin-1+i]*mask[i];
}
(*histogram)[bin] = smoothedValue;
}
My Questin is: Is it resonable to copy the histogram in a extra vector first so that when I smooth at bin i I can use the original i-1 value or would I simply do smoothedValue += (*histogram)[bin-1+i]*mask[i];, so that I use the already smoothed i-1 value instead the original one.
Regards & Thanks for a reply.
Your intuition is right: you need a temporary vector. Otherwise, you will end up using partly old values, and partly new values, and the result will not be correct. Try it yourself on paper with a simple example.
There are two ways you can write this algorithm:
Copy the data to a temporary vector first; then read from that one, and write to histogram. This is what you did in your first code fragment.
Read from histogram and write to a temporary vector; then copy from the temporary vector back to histogram.
To prevent needless copying of data, you can use vector::swap. This is an extremely fast operation that swaps the contents of two vectors. Using strategy 2 above, this would result in:
vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;
vector<double> newHistogram(histogram->size());
for (int bin = 1; bin < histogram->size()-1; bin++) {
double smoothedValue = 0;
for (int i = 0; i < mask.size(); i++) {
smoothedValue += (*histogram)[bin-1+i]*mask[i];
}
newHistogram[bin] = smoothedValue;
}
histogram->swap(newHistogram);

Resources