Line Detection How to decide which lines to keep - opencv

I have a task where I need to detect power lines in the video. For example, here is an image taken from the video:
Line is bright target in the video, so I used close operation to make it more clear. Then I used LSDDetect to detect lines. Then I get a collection of detected lines which are represented by end points. Here is the result:
But because the background is complex, I got many small lines that I don't want. I can filter most of them out by defining line angle(approximately 90 degree) and view field(x coordinate value range).
The problem is that the value is defined by me. How can I make the program calculate the proper angle and view field automatically? Or is there a better solution?
I'm new to opencv. Now I'm just using the library that opencv provides me, like the LSDDetect function, I don't know how they are implemented.

Related

Animating line graph with circular points

I have stumbled upon an interesting problem and I am not sure how to solve it. I have a line graph on which data points are marked with circular dots. At the moment I am creating one CAShapeLayer for the line itself and also CAShapeLayer for each dot.
The line is being animated with the strokeEnd animation key path. And it is working. However, the slightly negative effect is that once I open the graph I see all the data points already drawn and then a line is being animated through them.
Ideally I would like to change this behaviour in such a way that at the beginning nothing is shown and as the line gets animated data points are being drawn once the line passes through them.
I was thinking about this problem for some time now and I cannot find an elegant way of solving it. It seems to me that there should be a fairly easy way of achieving what I want. Maybe I should create a compounded path (but then how do I specify that a line needs to be stroked whereas dots need to be filled?).
Could anyone please guide me in the right direction?
There are lots of ways to handle this.
Assuming that the X increments of your graph are constant, and you're using linear timing, you could simply divide the total animation time by the number of data-points, and calculate the times when you need to add points to the graph when the line progresses to that X position. Simply add dot shape layers to the parent view's layer at the appropriate time intervals.
You could also change your drawing method to add new line segments to your graph path one at a time, on a timer, and add dot shapes at the same time. That would give you a step-by-step animation rather than a smooth line drawing.

How do I "parse" image locations on a minimap with OpenCV (or other tool)?

I've been trying to work on a small hobby project that involves plotting players' positions from a game onto a heatmap, to see where the most active areas are at various points in time.
I'm a bit new to OpenCV and its tools, but I've managed to successfully run some text matching and extraction on the scoreboard and timers in the game, now trying to take the characters' positions from the in-game minimap.
It looks like this, which is the biggest resolution image I'm able to get with (about 185x185):
I'm trying to obtain the positions of only two things: the characters (big circles) and "wards", which are represented by these icons:
So given the assets to them, I thought that because there was too much "noise" in the source image, I'd try to subtract the background of in game minimap from its image, and then try to pattern match the original character and ward image with the resulting image together (which is meant to be the minimap, minus its background). But that didn't even get close to working as you can see:
> >
Even if that did work, I wouldn't be really sure how to handle cases where the icons are partially covering each other, or how I could obtain the positions of those little ward markers.
I'd really appreciate some help, as I've been searching the Internet and banging my head for a few days and haven't gotten anywhere. I've tried a bunch of difference techniques, read guides and articles, and tried a few GUI tools to experiment with but haven't gotten any closer to a method to work this out.
Please help me with what techniques I could or should be using instead, to get the locations of all the characters and wards.
I'm not an OpenCV user, but I can speak to some general problems.
First and foremost, you goofed in subtracting the background map. It appears that you did a straight, arithmetic subtraction of the map's RGB values. For instance, the blue-team icons in the lower-left corner are roughly #99FFFF, and you're subtracting the grayish background of maybe #D0D0FF. This leaves you with #002F00, a very dark green.
Also note that you're subtracting the original map, not the part that shows. Paths beyond view are shaded, but you appear to subtract the original value.
What you need to subtract is a masked background. Unfortunately, building that mask means that you have to find the icons. Masking won't work well at this stage.
Back to the subtraction: don't just blindly subtract. Rather, look for a match in hue. When you find a hue match, simply set that pixel to 0. You have two special cases to watch: icons on the background of their own colour, especially for the blue team. In this case, you need to define the region boundaries.
Start from a pixel that's an exact match to the original background. It won't be shaded, since all such problem pixels are in plain sight of an icon. Expand from that pixel so long as you have the exact match to the original background colour. That will give you the region you can blank out.
Your next problem is to identify icons. You should now have a map with only icons, many of which are fully revealed. Those are easy matches; identify and subtract them, one key icon at a time.
You now have a map of partial icons. Switch the match algorithm: a key icon is now a match to either the exact color, or to black (indicating it was previously covered). Iterate until you have no more matches.
This does still leave you with one problem: an icon that no longer has enough pixels showing to identify. These will be icons that were either entirely covered, or covered except for a small portion that is not unique, such as a few pixels of a red circular border.
For this, a general approach is to keep track of game progress to a small extent: from an earlier time, you know where the icon used to be. Track each icon as a software object. If other icons cover it, assume it's still there until you discover otherwise.
This will handle most cases. You'll still have some problems with minions or sensors that get shot out from underneath a legend's icon, but I trust that your heat map application is not so fragile as to take modelling damage from that situation. The legend will move soon enough, revealing the small item's death. A moving minion isn't covered by a legend for long; they don't move with the same intelligence.

Interact with complex figure in iOS

I need to be able to interact with a representation of a cilinder that has many different parts in it. When the users taps over on of the small rectangles, I need to display a popover related to the specific piece (form).
The next image demonstrates a realistic 3d approach. But, I repeat, I need to solve the problem, the 3d is NOT required (would be really cool though). A representation that complies the functional needs will suffice.
The info about the parts to make the drawing comes from an API (size, position, etc)
I dont need it to be realistic really. The simplest aproximation would be to show a cilinder in a 2d representation, like a rectangle made out of interactable small rectangles.
So, as I mentioned, I think there are (as I see it) two opposite approaches: Realistic or Simplified
Is there a way to achieve a nice solution in the middle? What libraries, components, frameworks that I should look into?
My research has led me to SceneKit, but I still dont know if I will be able to interact with it. Interaction is a very important part as I need to display a popover when the user taps on any small rectangle over the cylinder.
Thanks
You don't need any special frameworks to achieve an interaction like this. This effect can be achieved with standard UIKit and UIView and a little trigonometry. You can actually draw exactly your example image using 2D math and drawing. My answer is not an exact formula but involves thinking about how the shapes are defined and break the problem down into manageable steps.
A cylinder can be defined by two offset circles representing the end pieces, connected at their radii. I will use an orthographic projection meaning the cylinder doesn't appear smaller as the depth extends into the background (but you could adapt to perspective if needed). You could draw this with CoreGraphics in a UIView drawRect.
A square slice represents an angle piece of the circle, offset by an amount smaller than the length of the cylinder, but in the same direction, as in the following diagram (sorry for imprecise drawing).
This square slice you are interested in is the area outlined in solid red, outside the radius of the first circle, and inside the radius of the imaginary second circle (which is just offset from the first circle by whatever length you want the slice).
To draw this area you simply need to draw a path of the outline of each arc and connect the endpoints.
To check if a touch is inside one of these square slices:
Check if the touch point is between angle a from the origin at a.
Check if the touch point is outside the radius of the inside circle.
Check if the touch point is inside the radius of the outside circle. (Note what this means if the circles are more than a radius apart.)
To find a point to display the popover you could average the end points on the slice or find the middle angle between the two edges and offset by half the distance.
Theoretically, doing this in Scene Kit with either SpriteKit or UIKit Popovers is ideal.
However Scene Kit (and Sprite Kit) seem to be in a state of flux wherein nobody from Apple is communicating with users about the raft of issues folks are currently having with both. From relatively stable and performant Sprite Kit in iOS 8.4 to a lot of lost performance in iOS 9 seems common. Scene Kit simply doesn't seem finished, and the documentation and community are both nearly non-existent as a result.
That being said... the theory is this:
Material IDs are what's used in traditional 3D apps to define areas of an object that have different materials. Somehow these Material IDs are called "elements" in SceneKit. I haven't been able to find much more about this.
It should be possible to detect the "element" that's underneath a touch on an object, and respond accordingly. You should even be able to change the state/nature of the material on that element to indicate it's the currently selected.
When wanting a smooth, well rounded cylinder as per your example, start with a cylinder that's made of only enough segments to describe/define the material IDs you need for your "rectangular" sections to be touched.
Later you can add a smoothing operation to the cylinder to make it round, and all the extra smoothing geometry in each quadrant of unique material ID should be responsive, regardless of how you add this extra detail to smooth the presentation of the cylinder.
Idea for the "Simplified" version:
if this representation is okey, you can use a UICollectionView.
Each cell can have a defined size thanks to
collectionView:layout:sizeForItemAtIndexPath:
Then each cell of the collection could be a small rectangle representing a
touchable part of the cylinder.
and using
collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
To get the touch.
This will help you to display the popover at the right place:
CGRect rect = [collectionView layoutAttributesForItemAtIndexPath:indexPath].frame;
Finally, you can choose the appropriate popover (if the app has to work on iPhone) here:
https://www.cocoacontrols.com/search?q=popover
Not perfect, but i think this is efficient!
Yes, SceneKit.
When user perform a touch event, that mean you knew the 2D coordinate on screen, so your only decision is to popover a view or not, even a 3D model is not exist.
First, we can logically split the requirement into two pieces, determine the touching segment, showing right "color" in each segment.
I think the use of 3D model is to determine which piece of data to show in your case if I don't get you wrong. In that case, the SCNView's hit test method will do most of work for you. What you should do is to perform a hit test, take out the hit node and the hit's local 3D coordinate of this node, you can then calculate which segment is hit by this touch and do the decision.
Now how to draw the surface of the cylinder would be the only left question, right? There are various ways to do, for example simply paint each image you need and programmatically and attach it to the cylinder's material or have your image files on disk and use as material for the cylinder ...
I think the problem would be basically solved.

How to separate the query and the train image from the Mat object returned from DrawMatches() method

I am trying to detect an object in a video. i am using SURF as feature detection and descriptor extractor, and BRUTFORCE as matcher. i tested my work with faces, i captured a picture of me and when i run the camera and direct it toward me, my face gets detected and a rectangle is drawn around it. i tried to make another test, i captured an image of my mouse and resized it, and when i run the cam, it is not getting detected
the problems i am facing are:
1-is the size of the query/object image matters in such cases,? i am asking this question because the image i captured of my self is bigger than the one of the mouse, and the face is getting detected and the mouse not.
2-regardless of which image i am using as a query/object iamge, how to display camera preview of only the train/scene image without the query/object image. i am asking this question because, what i am getting is something as shown in the below posted images, while what i want to do is something as it is shown here, i checked the code in that link, it is in C++ but i followed the same thing and also the tutorial uses 'drawMatches' method which has a peer in java which is Features2D.DrawMatches() and both of them returns a Mat object with the query/object image on the left side and the train/scene image on the right side as also shown in the image i posted below.
what i want to do is, to display on the the camera output without the query/object image, i want the area designated for the camera output is to show only the train/scene image captured from the camera.
please let me know how to solve this issues, i want to do something as shown in the tutorial i cited in the link.
1 - size matters but in your case, I think the most crucial problem is "textureness". SURF detect the interest points where the "texture gradient" is strong. In the case of your mouse, the gradient is mainly smooth, except aroud the logo (fujitsu), the button and at the border of the image. In the tutorial you point to, you notice it uses a very textured object to demonstrate the effect.
2 - to the best of my knowledge, there is fully automatic method to do what you want, but it can be done with a few steps. Basically, you must determine the surrounding box of your object then draw it. To draw, the easier is to use cv::rectangle but you can be more precise with four (or more....) cv::line. To determine the surrounding box, you can estimate the extreme points among the filtered matches.
Good luck!

Shape changing blobs

Ok, I'm not quite sure if this is something I can ask here so no need to shoot me down. Just tell me and i'll delete the question :)
I had this idea of making my own clock using a touch screen and program it myself.
While thinking about this I thought of all these different styles to show the current time.
Of all the styles I came up with there was one that I found the most fun which is a clock displaying the time Rorschach style. And no not just a random smudge and guess what time it is but more like Rorschach in watchmen.
He has a mask with inkblots that constantly change shape (really cool if you ask me).
So what I had in mind is inkblots that change shape according to the digit it represents.
When the time changes
12:49:58 -> 12:49:59 the 2nd second digit will transform from 8 -> 9.
So now back to the original problem:
Before attempting to get this type of clock running I want to try to give a blob a certain shape and make it transform into another shape.
I searched on google but without any luck so I was hoping there was someone here that could point me in the right direction for making a random blob and transform it into another shape in an animation.
For example:
Draw square -> animate to circle
Any tips and tricks are welcome :)
In order to get the most simpliest animation of digit transformation you could store all posible digits in one image (verticaly) and then only partially show that image in your component. So when you want to do transformation between one digit to another you simply slide the image up and down.
Now if you are using FireMonkey you could create a 3D viewport and inside it create a cylindical object onto which will you render your texture with digits. So now you only rotate the cilinder in order to show the corect digit.

Resources