Giter Club home page Giter Club logo

squarefinding's Introduction

Introduction

This is a personal project to find square in an image. I wanted to try image processing, find a square was a pretty good idea for me, so I decided to do it. In the following part, we'll consider a square like a square-like shape. It is now an archive, if you have any question -> Th0rOnDoR.#6925 on discord

Different ways to do it

In any case, we'll consider that we're working on a black and white image which is under the matrix form, for example:

    image = [[0,0,0,1,0,0], #this is an example of a smala image
            [0,0,1,0,1,0],  #i wanted to find square in way bigger one (240x40 at least)
            [0,1,0,0,0,1],
            [0,1,0,1,1,0],
            [0,0,1,0,0,0]]

First of all, by finding corners

This is the first way, I tried to find and check if the 4 max/min points are different. Firstly, we suppose that the point corresponding to A(xmax,k) is a corner, and so on for xmin, ymax, ymin. We have 4 points: A(Xmax,y1) B(xmin,y2) C(x1,Ymax) D(x2,ymin)

Then we check if A != B != C != D. This was for me, the easiest , fastest and best way to find square. But, I have some kind of interference in my images.

    1000000000000000100000000000000
    0000000000000001000000000000000 #here, we can easily see that the main shape is a square but, in fact
    0000000000000001000000000000000 #it won’t be detected as a square. Why ?
    1000000000000010100000000000000 #Because here, we have 
    1000000000000100010000000000000 #A(Xmax,k1) = A(24,15)
    1000000000000100010000000000000 #B(xmin,k2) = B(1,1)
    1000000000001000001000000000000 #C(Ymax,k3) = (14,37)
    0000000000001000001000000000000 #D(ymin,k4) = (1,1)
    0000000000010000000100000000000
    0000000000100000000010000000000
    1000000000100000000010000000000
    0000000010000000000000100000000
    1000000010000000000000100000000
    1000000100000000000000010000000
    0000001000000000000000001000000
    0000001000000000000000001000000
    0000010000000000000000000100000
    0000100000000000000000000010000
    0000100000000000000000000010000
    0001000000000000000000000001000
    1001000000000000000000000001000
    1100000000000000000000000010000
    1010000000000000000000000100000
    1010000000000000000000000100000
    1001100000000000000000001000000
    1000010000000000000000010000000
    0000010000000000000000010000000
    1000001000000000000001100000000
    1000000000000000000001100000000
    1000000100000000000010000000000
    1000000011000000000100000000000
    1000000011000000000100000000000
    0000000000100000001000000000000
    0000000000010000010000000000000
    0000000000010000010000000000000
    0000000000001100100000000000000
    0000000000001100100000000000000
    0000000000000010000000000000000

So, I gave up this way.

Another way, processing by shape

I contacted a German developer (https://github.com/alexanderthiem) and asked him how he did it. In fact, Alexander is a 17 years old man, passionate about numeric world and he's a developer with more experience than me in this field. He had already done something similiar ~10 months ago. He answered he was doing the exact same thing, but with more maths and, above all, by splitting the main image in different shapes.

As far as I remember my code, i took the image of the screen by using a Library and converted it to a 2 Dimensional List. I then sorted this list into 0 and 1 (based on the brightness I guess). This List of Pixels was then splitted into shapes by finding connected and unconnected groups of pixels. Then I analyzed each shape similar to this: M=Midpoint of all Pixels being 1 A= The point with the highest distance to M B=The point with the highest distance to the line AM (Using Vectors to generate a formula for the distance) C= The Point with highest distance to the line AB

Then I calculated for every point (being 1) the distance to the lines AB,BC,CA took the minimum of those three values and summed it up: S= Sum(For each point=1, minimum(distanceToAB,distanceToBC,distanceToCA))

If this Sum was smaller than a given constant, the shape was treated as a triangle

So, that’s what I tried. I have split the shape and then, found A,B,C,D with my own method. This corresponds to the files 1.py to 3.py (except i added another test in 3.py). In fact, I’ve done one every shape 3 test: if A != B != C != D if AB = BC = CD = DA if the intersection point between [AC] and [BD] is the same point as the average point (Sum of X / number of point, Sum of Y/number of point)

Don't look at the memory and time required

Unfortunatly, this way wasnt working. Then, I remember that someone once said "Straighter it worksheet" (Plus droit, ca passe in French), in another way: bruteforce. So I tried a bruteforce-like method.

For each shape, I selected 4 points, but I cannot say "hmm, I'll take these 4 points" so, I made a loop, in a loop, in a loop, in a loop to get all of 4 points combinations. Then, for each combination, I looked if it made a square by testing dist between points and if the length between the ? isn’t too short or too long. But, this time, some triangles were detected as square...

    0000000000000010000000
    0000000000000101000000
    0000000000000101000000
    0000000000001001000000
    0000000000010000100000 #there is a triangle here
    0000000000010000100000 #The detected square is highlighted with '/' and '-'
    0000000000100000100000 #'/' if it was a 1
    0000000000100000100000 #'-' if it was a 0
    0000000011000000010000
    0000000//--------/0000
    0000000/000000000/0000
    0000001-000000000-1000
    0000010-000000000-1000
    0000010-000000000-1000
    0000100-000000000-0100
    0000100-000000000-0100
    0000000-000000000-0100
    0000000-000000000-0010
    0000001/111110000-0010
    0000001///////////1110

These methods correspond to files 5 to 7. In each file, I added more tests but, this way wasn’t accurate enough (~30%) and, worst, it took so much time that I can leave home, buy some bread and return before all images are finished (it did 30 out of 50).

Does it work if we use maths power?

First, we cut the image into shapes. What if we look for every line and then, analyze them with some maths formulas? For example, for every line, we take the two extreme points then, we get the director vector. Be A(xa;ya) , B(xb;yb) the extreme point, a director vector will be u(xb-xa;yb-ya). The line's equation will be (-yb+ya)*x + (xb-xa)*y + c = 0. A normal vector to our line is n(-yb+ya;xb-xa). Then, without knowing the value of the constant c, we can’t find any perpendicular line. A perpendicular line is a line with a director vector equals to the normal vector of our line, which we know. So, let’s process. We get every director vector and every normal vector and add them to a list and, we look for an almost perpendicular line. We want two of them and for those two, we look if there are two perpendicular lines. This way, we have 4 lines, 2 by 2 perpendicular. Like a square.

The main problem of this way is: It took too much time and space. Why? Because it took way too much time to find each line and I dont even speak of the loop to look for perpendicular lines.

The Last solution. The artificial Intelligence

Sure, that's not an IA because I don't have enough knowledge of how it works but, I find a way to find a square by looking for a known square. Like an IA will do, learn what a square is, and look for something similar. What do I mean ? I mean registering a file image of a square then, try in another image if there is something similar. What do I mean by something similar? I mean another square, sure, in fact, I Check et for each point (point being 1 only) if a point nearby corresponds to the next point of a known square. In other words, I listed all points of every known squares and then, for each point of the image I considered if the first point of the known square and count how many other points correspond to this square. This way, I have a variable 'good point' which I divided by the number of points of the known square to get a ratio. Then, I suppose that’s the better ratio corresponding to the square.

The main problem of this version is, if you don’t know what you are looking for in reality, you won’t be able to find it with mathematic formula only.

For exemple:

    0000000000000000110000000000000000000000
    0000000000000000011100000000000000000000
    0000000000000000100011000000000000000000
    0000000000000000100011000000000000000000
    0000000000000001000000111000000000000000
    0000000000000001000000111000000000000000
    0000000000000001000000000110000000000000
    0000000000000010000000000001100000000000
    0000000000000010000000000001100000000000
    0000000000000100000000000000000000000000
    0000000000001000000000000000100000000000
    0000000000001000000000000000100000000000
    0000000000001000000000000001000000000000
    0000000000001000000000000001000000000000
    0000000000010000000000000001000000000000
    0000000000100000000000000010000000000000
    0000000000100000000000000010000000000000
    0000000000100000000000000010000000000000
    0000000001000000000000000100000000000000
    0000000001000000000000000100000000000000
    0000000001000000000000001000000000000000
    0000000001000000000000001000000000000000
    0000000000110000000000001000000000000000
    0000000000001100000000010000000000000000
    0000000000001100000000010000000000000000
    0000000000000011000000010000000000000000
    0000000000000000110000100000000000000000
    0000000000000000110000100000000000000000
    0000000000000000001100100000000000000000
    0000000000000000001100100000000000000000
    0000000000000000000011000000000000000000

Now, here's an image (real dimensions)

    0000000000000000000000000000000000000000
    0000000000000000000000100000000000000000
    0000000000000000000000100000000000000000
    0000000000000000000000100000000000000000
    0000000000000000000000101000000000000000
    0000000000000000000000101000000000000000
    0000000000000000000000110000000000000000
    0000000000000000000000110000000000000000
    0000000000000000000001100000000000000000
    0000000000000000000110100000000000000000
    0000000000000000000110100000000000000000
    0000000000000000001001000000000000000000
    0000000000000000110001000000000000000000
    0000000000000000110001000000000000000000
    0000000000000001000001000000000000000000
    0000000000000001000001000000000000000000
    0000000000000110000001000000000000000000
    0000000000001000000001000000000000000000
    0000000000001000000001000000000000000000
    0000000000110000000001000000000000000000Th0rOnDoR/Babyfootsmc
    0000000001000000000001000000000000000000
    0000000001000000000001000000000000000000
    0000000110000000000001000000000000000000
    0000000000000000000001000000000000000000
    0000001000000000000001000000000000000000
    0000110000000000000001000000000000000000
    1100110000000000000001000000000000000000
    0101000000000000000001000000000000000000
    0110000000000000000001000000000000000000
    0110000000000000000001000000000000000000
    1110000000000000000010000000000000000000
    1110000000000000000010000000000000000000
    0001111000000000000010000000000000000000
    0000000111100000000010000000000000000000
    0000000111100000000010000000000000000000
    0000000000011111000010000000000000000000
    0000000000000000110110000000000000000000
    0000000000000000111110000000000000000000
    0000000000000000000011100000000000000000
    0000000000000000000011000000000000000000
    0000000000000000000000000000000000000000
    0000000110000000000000000000000000000000
    0000000001111000000000000000000000000000
    0000000001111000000000000000000000000000
    0000010000000111000000100000000000000000
    0000001000000000111000100000000000000000
    0000001000000000111100100000000000000000
    0000000100000000000011000000000000000000
    0000000100000000000011000000000000000000
    0000000100000000000001000000000000000000
    0000000010000000000010000000000000000000
    0000000010000000000010000000000000000000
    0000000001000000000010000000000000000000
    0000000000100000000110000000000000000000
    0000000000100000000100000000000000000000
    0000000000010000000100000000000000000000
    0000000000010000000100000000000000000000
    0000000000010000000100000000000000000000
    0000000000001000001000000000000000000000
    0000000000001000001000000000000000000000
    0000000000000100001000000000000000000000
    0000000000000010010000000000000000000000
    0000000000000010010000000000000000000000
    0000000000000010010000000000000000000000
    0000000000000010010000000000000000000000
    0000000000000001100000000000000000000000
    0000000000000000100000000000000000000000
    0000000000000000100000000000000000000000
    0000000000000000001000000000000000000000
    0000000000000000110000000000000000000000
    0000000000000000110000000000000000000000
    0000000000000000011100000000000000000000
    0000000000000000100011000000000000000000
    0000000000000000100011000000000000000000
    0000000000000001000000111000000000000000
    0000000000000001000000111000000000000000
    0000000000000001000000000110000000000000
    0000000000000010000000000001100000000000
    0000000000000010000000000001100000000000
    0000000000000100000000000000000000000000
    0000000000001000000000000000100000000000
    0000000000001000000000000000100000000000
    0000000000001000000000000001000000000000
    0000000000001000000000000001000000000000
    0000000000010000000000000001000000000000
    0000000000100000000000000010000000000000
    0000000000100000000000000010000000000000
    0000000000100000000000000010000000000000
    0000000001000000000000000100000000000000
    0000000001000000000000000100000000000000
    0000000001000000000000001000000000000000
    0000000001000000000000001000000000000000
    0000000000110000000000001000000000000000
    0000000000001100000000010000000000000000
    0000000000001100000000010000000000000000
    0000000000000011000000010000000000000000
    0000000000000000110000100000000000000000
    0000000000000000110000100000000000000000
    0000000000000000001100100000000000000000
    0000000000000000001100100000000000000000
    0000000000000000000011000000000000000000

Now, you may be thinking 'what if the square doesn’t exactly look like this one, what if it rotates ?'. And I'll answer you: You cannot find it with this method. That’s why I think this is the worst way of doing this but, with this way, I can just register the unkown square and it will 'learn' from it. In fact, this way has a way better ratio than the others methods, on ~8000 test, it succesfully detects the square with a 0,82 ratio.

Installation

So, to install any file, you only need python. Be sure to have something to convert images to binary text file

Usage

Nothing, i don't find how this version could be used. But, a better version (something done by a professional, someone who has more experience than me) can be used in many ways, finding a house from the sky, find doors in a house for someone blind, it could be used to find a lot of things for someone who can’t do it by himself .

Any questions? Th0rOnDoR.#6925

squarefinding's People

Contributors

th0rondor avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.