Halcon - Get a score for branches - shapes

I need to find shapes that have many branches.. But with only the region_features i'm not able to make this work.
basically, I'd need a score for a "branch factor".. for example, a star would have a rather high score, since each tip would be a branch.. a picture of a tree-branch would have a high score, since it has many smaller branches.. A sphere, or a cube would have a low score since it does not have many branches..
I have tried with the proportion between area and circumference, but its not precise enough..
here are 2 samples.. one that hsould have a high score, and one that should have a low score:
These are only samples to explain what I mean by branches.. the shapes can have any form..

No, there is not this kind of parameter.
Maybe you can extract this parameter with a code like:
* load image example
read_image(Image,'ppUXL.jpg')
* create 4 Regions
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
connection (Region, Regions)
count_obj (Regions,NumRegions)
NumBranches :=[]
* for every region in Regions
for i:=1 to NumRegions by 1
* select the region
select_obj (Regions, RegionSelected, i)
* --------------------------------------------------------------------------
* Here I want to calculate the region convex hull,
* i.e. the smallest region convex region that contains the selected region
* https://en.wikipedia.org/wiki/Convex_hull
* --------------------------------------------------------------------------
* convex hull of a region as polygon
get_region_convex (RegionSelected, Rows, Columns)
* trasform the polygon in a region
gen_region_polygon_filled (ConvexRegion, Rows, Columns)
* For avoiding to merge separeted parts, I erode a little the convex region
erosion_circle (ConvexRegion, RegionErosion, 1.5)
* Now I remove the selected region from its convex (erosed) region.
* In most of the case the results is the space between the branches
difference (RegionErosion, RegionSelected, RegionDifference)
* --------------------------------------------------------------------------
* I separate the space between the branches and I count the its number
* --------------------------------------------------------------------------
* connection
connection (RegionDifference, InsideRegions)
* I remove empy regions
select_shape (InsideRegions, InsideSelectedRegions, 'area', 'and', 1, 99999999)
* I count the regions
count_obj (InsideSelectedRegions,NumInsideRegions)
* I add the result to the array
NumBranches :=[NumBranches,NumInsideRegions]
endfor

Related

Find records by given latitude and longitude which intersects and circle within 2 mile radius using PostGIS?

I have a Postgres table with some data created by using a shapefile. I need to find all records which intersect within 2 miles radius from a given latitude and longitude. I used some queries including the following one.
SELECT * FROM us_census_zcta WHERE ST_INTERSECTS(geom,
CIRCLE(POINT(40.730610, -73.935242), 2));
But none of them worked. What I am doing wrong here? How can I get the results I need?
The SRID is 4269 (NAD 83).
EDIT: After Mike Organek pointed me out that I have switched the lat-long in the above query. And then I tried a few things and the following query gave me 1 record.
SELECT * FROM us_census_zcta WHERE ST_INTERSECTS(geom::geometry,
ST_SETSRID(ST_POINT(-73.935242, 40.730610), 4269)::geometry);
But how can I use Circle and find records which intersect within 2 miles radius from that given lat-long?
What you're looking for is ST_DWithin, which will check if records intersect within a given buffer. In order to use it with miles you better cast the geometry column to geography, as it then computes distances in metres:
For geography: units are in meters and distance measurement defaults to use_spheroid=true. For faster evaluation use use_spheroid=false to measure on the sphere.
SELECT * FROM us_census_zcta
WHERE
ST_DWithin(
geom::geography,
ST_SetSRID(ST_MakePoint(-73.935242, 40.730610), 4269)::geography,
3218.688); -- ~2 miles
Keep in mind that this cast might affect query performance if the indexes aren't set properly.
See also: Getting all Buildings in range of 5 miles from specified coordinates

How to get longitude and latitude for a place within certain distance from a known longitude and latitude

I want to find a place (longitude and latitude) with distance less than 10 km from a known longitude and latitude using BigQuery SQL. Is there any possible query for this?
I read your request as saying that given a geospatial point, you wish to query for anything within less than a 10km radius of that point. Here's two ways to solve this:
Using ST_BUFFER
You could use the ST_BUFFER function which similarly takes an argument of the radius to use around a point, but instead uses a segmented circle with 8 segments by default.
SELECT *
FROM `table`
WHERE ST_CONTAINS(
ST_BUFFER(
ST_GEOPOINT(longitude, latitude),
10 * 1000), -- Radius argument is expressed in meters
YourGeoPointColumn)
Using ST_BUFFERWITHTOLERANCE
You might use ST_BUFFERWITHTOLERANCE that replaces the segmented circle with tolerance instead of circle segments.
SELECT *
FROM `table`
WHERE ST_CONTAINS(
ST_BUFFERWITHTOLERANCE(
ST_GEOPOINT(longitude, latitude),
10 * 1000, -- Radius argument is expressed in meters
1), -- Tolerance of 1% of the buffer radius, expressed in meters
YourGeoPointColumn)
ST_Distance function should work here, like this:
with data as (
select 1 id, st_geogpoint(-122, 47) as geo
union all
select 2 id, st_geogpoint(-121, 47) as geo
)
select * from data
where st_distance(geo, st_geogpoint(-122.1, 47)) < 10000
id geo
------------------
1 POINT(-122 47)
Another way to write the distance condition is
ST_DWithin(geo, st_geogpoint(-122.1, 47), 10000)
If something does not work, please provide sample data and what data you expect in the results but is missing.

How can I select the largest region in HALCON?

I want to select the largest region from a tuple of regions (ConnectedRegions in this case).
threshold (Image, Region, 250, 255)
connection (Region, ConnectedRegions)
* TODO: Get the largest region in ConnectedRegions
What is an elegant way to achieve this?
Updated Answer
Use select_shape_std:
select_shape_std (ConnectedRegions, MaxRegion, 'max_area', 0)
For other selections criteria, there is select_shape.
Original Answer
With three operators, you can solve the task in the example: area_center, tuple_sort_index and select_obj
threshold (Image, Region, 250, 255)
connection (Region, ConnectedRegions)
* Get the area of each region. R and C return values are not used.
area_center (ConnectedRegions, Areas, R, C)
* Get the indices to sort the areas in descending order.
tuple_sort_index (- Areas, SortIndices)
* Select the region using the first index.
* We need to add 1, because control tuples use 0-based indexing,
* while object tuples are 1-based
select_obj (ConnectedRegions, MaxRegion, SortIndices[0] + 1)

How to find distance between two points using latitude and longitude

I have a ROUTES table which has columns SOURCE_AIRPORT and DESTINATION_AIRPORT and describes a particular route that an airplane would take to get from one to the other.
I have an AIRPORTS table which has columns LATITUDE and LONGITUDE which describes an airports geographic position.
I can join the two tables using columns which they both share called SOURCE_AIRPORT_ID and DESTINATION_AIRPORT_ID in the routes table, and called IATA in the airports table (a 3 letter code to represent an airport such as LHR for London Heathrow).
My question is, how can I write an SQL query using all of this information to find, for example, the longest route out of a particular airport such as LHR?
I believe I have to join the two tables, and for every row in the routes table where the source airport is LHR, look at the destination airport's latitude and longitude, calculate how far away that is from LHR, save that as a field called "distance", and then order the data by the highest distance first. But in terms of SQL syntax i'm at a loss.
This would have probably been a better question for the Mathematics Stack Exchange, but I’ll provide some insight here. If you are relatively farmiliar with trigonometry, I’m sure you could understand the implementation given this resource: https://en.m.wikipedia.org/wiki/Haversine_formula. You are looking to compute the distance between two point on the surface of a sphere in terms of their distance across its surface (not a straight line, you can’t travel through the Earth).
The page displays this formula:
https://wikimedia.org/api/rest_v1/media/math/render/svg/a65dbbde43ff45bacd2505fcf32b44fc7dcd8cc0
Where
• φ1, φ2 are the latitude of point 1 and latitude of point 2 (in radians),
• λ1, λ2 are the longitude of point 1 and longitude of point 2 (in radians).

If you data is in degrees, you can simply convert to radians by multiplying by pi/180
There is a formula called great circle distance to calculate distance between two points. You probably can load is as a library for your operating system. Forget the haversine, our planet is not a perfect sphere.
If you use this value often, save it in your routes table.
I think you're about 90% there in terms of the solution method. I'll add in some additional detail regarding a potential SQL query to get your answer. So there's 2 steps you need to do to calculate the distances - step 1 is to create a table containing joining the ROUTES table to the AIRPORTS table to get the latitude/longitude for both the SOURCE_AIRPORT and DESTINATION_AIRPORT on the route. This might look something like this:
SELECT t1.*, CONVERT(FLOAT, t2.LATITUDE) AS SOURCE_LAT, CONVERT(FLOAT, t2.LONGITUDE) AS SOURCE_LONG, CONVERT(FLOAT, t3.LATITUDE) AS DEST_LAT, CONVERT(FLOAT, t3.LONGITUDE) AS DEST_LONG, 0.00 AS DISTANCE_CALC
INTO ROUTE_CALCULATIONS
FROM ROUTES t1 LEFT OUTER JOIN AIRPORTS t2 ON t1.SOURCE_AIRPORT_ID = t2.IATA
LEFT OUTER JOIN AIRPORTS t3 ON t1.DESTINATION_AIRPORT_ID = t3.IATA;
The resulting output should create a new table titled ROUTE_CALCULATIONS made up of all the ROUTES columns, the longitude/latitude for both the SOURCE and DESTINATION airports, and a placeholder DISTANCE_CALC column with a value of 0.
Step 2 is calculating the distance. This should be a relatively straightforward calculation and update.
UPDATE ROUTE_CALCULATIONS
SET DISTANCE_CALC = 2 * 3961 * asin(sqrt((sin(radians((DEST_LAT- SOURCE_LAT) / 2))) ^ 2 + cos(radians(SOURCE_LAT)) * cos(radians(DEST_LAT)) * (sin(radians((DEST_LONG- SOURCE_LONG) / 2))) ^ 2))
And that should give the calculated distance in the DISTANCE_CALC table for all routes seen in the data. From there you should be able to do whatever distance-related route analysis you want.

Optimizing Sqlite query for INDEX

I have a table of 320000 rows which contains lat/lon coordinate points. When a user selects a location my program gets the coordinates from the selected location and executes a query which brings all the points from the table that are near. This is done by calculating the distance between the selected point and each coordinate point from my table row. This is the query I use:
select street from locations
where ( ( (lat - (-34.594804)) *(lat - (-34.594804)) ) + ((lon - (-58.377676 ))*(lon - (-58.377676 ))) <= ((0.00124)*(0.00124)))
group by street;
As you can see the WHERE clause is a simple Pythagoras formula to calculate the distance between two points.
Now my problem is that I can not get an INDEX to be usable. I've tried with
CREATE INDEX indx ON location(lat,lon)
also with
CREATE INDEX indx ON location(street,lat,lon)
with no luck. I've notice that when there is math operation with lat or lon, the index is not being called . Is there any way I can optimize this query for using an INDEX so as to gain speed results?
Thanks in advance!
The problem is that the sql engine needs to evaluate all the records to do the comparison (WHERE ..... <= ...) and filter the points so the indexes don’t speed up the query.
One approach to solve the problem is compute a Minimum and Maximum latitude and longitude to restrict the number of record.
Here is a good link to follow: Finding Points Within a Distance of a Latitude/Longitude
Did you try adjusting the page size? A table like this might gain from having a different (i.e. the largest?) available page size.
PRAGMA page_size = 32768;
Or any power of 2 between 512 and 32768. If you change the page_size, don't forget to vacuum the database (assuming you are using SQLite 3.5.8. Otherwise, you can't change it and will need to start a fresh new database).
Also, running the operation on floats might not be as fast as running it on integers (big maybe), so that you might gain speed if you record all your coordinates times 1 000 000.
Finally, euclydian distance will not yield very accurate proximity results. The further you get from the equator, the more the circle around your point will flatten to ressemble an ellipse. There are fast approximations which are not as calculation intense as a Great Circle Distance Calculation (avoid at all cost!)
You should search in a square instead of a circle. Then you will be able to optimize.
Surely you have a primary key in locations? Probably called id?
Why not just select the id along with the street?
select id, street from locations
where ( ( (lat - (-34.594804)) *(lat - (-34.594804)) ) + ((lon - (-58.377676 ))*(lon - (-58.377676 ))) <= ((0.00124)*(0.00124)))
group by street;