How to detect an image border programmatically? - automation

I'm searching for a program which detects the border of a image,
for example I have a square and the program detects the X/Y-Coords
Example:
alt text http://img709.imageshack.us/img709/1341/22444641.png

This is a very simple edge detector. It is suitable for binary images. It just calculates the differences between horizontal and vertical pixels like image.pos[1,1] = image.pos[1,1] - image.pos[1,2] and the same for vertical differences. Bear in mind that you also need to normalize it in the range of values 0..255.
But! if you just need a program, use Adobe Photoshop.
Code written in C#.
public void SimpleEdgeDetection()
{
BitmapData data = Util.SetImageToProcess(image);
if (image.PixelFormat != PixelFormat.Format8bppIndexed)
return;
unsafe
{
byte* ptr1 = (byte *)data.Scan0;
byte* ptr2;
int offset = data.Stride - data.Width;
int height = data.Height - 1;
int px;
for (int y = 0; y < height; y++)
{
ptr2 = (byte*)ptr1 + data.Stride;
for (int x = 0; x < data.Width; x++, ptr1++, ptr2++)
{
px = Math.Abs(ptr1[0] - ptr1[1]) + Math.Abs(ptr1[0] - ptr2[0]);
if (px > Util.MaxGrayLevel) px = Util.MaxGrayLevel;
ptr1[0] = (byte)px;
}
ptr1 += offset;
}
}
image.UnlockBits(data);
}
Method from Util Class
static public BitmapData SetImageToProcess(Bitmap image)
{
if (image != null)
return image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite,
image.PixelFormat);
return null;
}
If you need more explanation or algorithm just ask with more information without being so general.

It depends what you want to do with the border, if you are looking at getting just the values of the edges of the region, use an algorithm called the Connected Components Region. You must know the value of the region prior to using the algorithm. This will navigate around the border and collect the outside region. If you are trying to detect just the outside lines get the gradient of the image and it will reveal where the lines are. To do this convolve the image with an edge detection filter such as Prewitt, Sobel, etc.

You can use any image processing library such as Opencv. which is in c++ or python.
You should look for edge detection functions such as Canny edge detection.
Of course this would require some diving into image processing.
The example image you gave should be straight forward to detect, how noisy/varied are the images going to be?

A shape recognition algorithm might help you out, providing it has a solid border of some kind, and the background colour is a solid one.

From the sounds of it, you just want a blob extraction algorithm. After that, the lowest/highest values for x/y will give you the coordinates of the corners.

Related

OpenTK ES 1.1 texture rendering

I have a method that I use to render little map using tiles, but when I finish rendering and I want to make a translation changing "transY" variable using different method nothing happens, so I must call RenderTesture() again to make it. How can I do this withot unnecessary rendering because it can slow down application when I use larger number of tiles?
void RenderTexture ()
{
MakeCurrent ();
GL.Clear((int)All.ColorBufferBit | (int)All.DepthBufferBit);
GL.MatrixMode(All.Modelview);
GL.LoadIdentity();
GL.Translate(-transX, transY, -10);
for (int i = 0; i < tileRows; i++)
{
for (int j = 0; j < tileColumns; j++)
{
GL.BindTexture(All.Texture2D, textureIds [i*tileColumns + j]);
GL.EnableClientState(All.VertexArray);
GL.EnableClientState(All.TextureCoordArray);
GL.PushMatrix ();
GL.Translate(j*2, -i*2, 0);
GL.VertexPointer(3, All.Float, 0, frontV);
GL.TexCoordPointer(2, All.Float, 0, frontT);
GL.DrawArrays (All.TriangleFan, 0, 4);
GL.PopMatrix ();
}
}
GL.DisableClientState(All.VertexArray);
GL.DisableClientState(All.TextureCoordArray);
SwapBuffers ();
}
If anybody have advice for me, I'll be very grateful!
Thanks in advance!
The bottleneck lies, most likely, in the amount of state changes (GL.BindTexture) and the amount of draw calls you are making (GL.DrawArrays). In general, you should draw as much as possible in a single draw call.
The simplest approach wold be to use a "texture atlas":
combine all your tile textures into a single large texture (this is the "texture atlas")
combine all your tile vertices into a single vertex array
call GL.BindTexture once to bind the texture atlas
call GL.DrawArrays once to render all tiles
So how do you render different tile textures? Simple: you change the vertex texture coordinates to point to the correct tile inside the texture atlas.
A single 1024x1024 can hold 256 distinct 64x64 tiles. Depending on the amount of distinct tiles in your game, you might have to use multiple texture atlases. Moreover, depending on the size of your map, you might wish to split it into "regions" with separate vertex arrays for each (you don't want to render 1 million tiles every frame if your monitor can only display 1000 tiles.)
On its own, this will give a measurable performance boost. Once this is working, you can get a second large boost by storing your vertex arrays on the GPU via Vertex Buffer Objects (VBOs).
Thank you very much!
The "Texture atlas" strategy can be very good idea. I've implemented that last night and it looks like rendering is getting speed. I've reduce loading of NxM tiles using separate textures, by loading one big NxM tiles bitmap using single texture and I've implemented method to change vertex array (in regard to new bitmap dimensions - NxM)
public void UpdateFrontVertex(int rowNumber, int columnsNumber)
{
for (int i = 0; i < 12; i++) {
if (i % 3 == 0)
frontVertex [i] = defaultFrontVertex[i] * rowNumber; // x-axis
else if (i % 3 == 1)
frontVertex [i] = defaultFrontVertex[i] * columnsNumber; // y-axis
else if (i % 3 == 2)
frontVertex [i] = defaultFrontVertex[i]; // z-axis
}
}
After that, I've got my map!!!
I still cannot compare performances before that implementation and now because I have to make changes for panning and zooming functionalities to work with that new rendering strategy.
For example, I've used
//zoom in
transY = (transY * 2 + 1);
transX = (transX * 2 + 1);
//zoom out
transX = ((transX - 1) / 2);
transY = ((transY - 1) / 2);
for zooming calculations to figure out which tile is my central tile, and after that to load all rounding tiles.
Thank you again for great help, I'll proceed now with panning and zooming implementation.

How to use open cv to detect black rectangles on the image ios [duplicate]

I am stuck with a problem that is how to recognize some patterns in image.
the image is the image of paper which is pure white and the patterns are in four corners are in black.
I want to recognize the black patterns on the image?
I surf a lot on the net and found that the opencv as a answer. but there is nothing provided that describe how to use opencv in order to achieve the required feature.
Please help me with some coding point of view or provide some link which I should follow or any name of any open source library which I should use to achieve this feature.
The image for pattern is below:-
The image consist of pure white background and four black patterns in the corner.I need to recognize these black patterns in the all four corners all then process the image.One corner shown in oval to highlight it.
Any suggestions will be highly appreciated.
Thanks in advance!
I really don't understand your problem - if you say:
The image is the image of paper which is pure white and the patterns
are in four corners are in black.
Then what's the problem to mask only these four contours from image? After doing mask with 4 squares with length 40 pixels I got this:
To remove small areas you can use morphological operations. I got this:
And just draw them (optional) on input image. Here's result:
To implement this algorithm I use OpenCV library. I'm 100% sure that it works on IOS - OpenCV team finally published IOS version. So if you say:
I tried running the OpenCV-iOS link but the project does not run, it
is showing errors.
Then we can't help you with that because we are not telepathists to see your problem. Just small suggestion - try to google your problem. I'm 99% sure that it should help.
And lest I forget - here's c++ code:
Mat src = imread("input.png"), tmp;
//convert image to 1bit
cvtColor(src, tmp, CV_BGR2GRAY);
threshold(tmp, tmp, 200, 255, THRESH_OTSU);
//do masking
#define DELTA 40
for (size_t i=0; i<tmp.rows; i++)
{
for (size_t j=0; j<tmp.cols; j++)
{
if(!((i < DELTA && j < DELTA)
|| (i < DELTA && j > tmp.cols - DELTA)
|| (i > tmp.rows - DELTA && j < DELTA)
|| (i > tmp.rows - DELTA && j > tmp.cols - DELTA)))
{
//set color to black
tmp.at<uchar>(i, j) = 255;
}
}
}
bitwise_not(tmp,tmp);
//erosion and dilatation:
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(1, 1));
erode(tmp, tmp, element);
dilate(tmp, tmp, element);
//(Optional) find contours and draw them:
vector<Vec4i> hierarchy;
vector<vector<Point2i> > contours;
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
for (size_t i=0; i<contours.size(); i++)
{
drawContours(src, contours, i, Scalar(0, 0, 255), 1);
}
Maybe this question is helpful for you, especially the link to the Tennis Ball Recognizing Tutorial seems to be pretty much what you are looking for.
Regarding how to use OpenCV on iOS you might want to take a look at OpenCV-iOS and Computer Vision with iOS.

pattern recognition while taking pictures and identify the patterns and do manipulation on image accordingly [duplicate]

I am stuck with a problem that is how to recognize some patterns in image.
the image is the image of paper which is pure white and the patterns are in four corners are in black.
I want to recognize the black patterns on the image?
I surf a lot on the net and found that the opencv as a answer. but there is nothing provided that describe how to use opencv in order to achieve the required feature.
Please help me with some coding point of view or provide some link which I should follow or any name of any open source library which I should use to achieve this feature.
The image for pattern is below:-
The image consist of pure white background and four black patterns in the corner.I need to recognize these black patterns in the all four corners all then process the image.One corner shown in oval to highlight it.
Any suggestions will be highly appreciated.
Thanks in advance!
I really don't understand your problem - if you say:
The image is the image of paper which is pure white and the patterns
are in four corners are in black.
Then what's the problem to mask only these four contours from image? After doing mask with 4 squares with length 40 pixels I got this:
To remove small areas you can use morphological operations. I got this:
And just draw them (optional) on input image. Here's result:
To implement this algorithm I use OpenCV library. I'm 100% sure that it works on IOS - OpenCV team finally published IOS version. So if you say:
I tried running the OpenCV-iOS link but the project does not run, it
is showing errors.
Then we can't help you with that because we are not telepathists to see your problem. Just small suggestion - try to google your problem. I'm 99% sure that it should help.
And lest I forget - here's c++ code:
Mat src = imread("input.png"), tmp;
//convert image to 1bit
cvtColor(src, tmp, CV_BGR2GRAY);
threshold(tmp, tmp, 200, 255, THRESH_OTSU);
//do masking
#define DELTA 40
for (size_t i=0; i<tmp.rows; i++)
{
for (size_t j=0; j<tmp.cols; j++)
{
if(!((i < DELTA && j < DELTA)
|| (i < DELTA && j > tmp.cols - DELTA)
|| (i > tmp.rows - DELTA && j < DELTA)
|| (i > tmp.rows - DELTA && j > tmp.cols - DELTA)))
{
//set color to black
tmp.at<uchar>(i, j) = 255;
}
}
}
bitwise_not(tmp,tmp);
//erosion and dilatation:
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(1, 1));
erode(tmp, tmp, element);
dilate(tmp, tmp, element);
//(Optional) find contours and draw them:
vector<Vec4i> hierarchy;
vector<vector<Point2i> > contours;
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
for (size_t i=0; i<contours.size(); i++)
{
drawContours(src, contours, i, Scalar(0, 0, 255), 1);
}
Maybe this question is helpful for you, especially the link to the Tennis Ball Recognizing Tutorial seems to be pretty much what you are looking for.
Regarding how to use OpenCV on iOS you might want to take a look at OpenCV-iOS and Computer Vision with iOS.

.NET CF 2.0: Draw an PNG over a image with background transparency

I want to draw an image over other without drawing its backgroud. The image that I want to draw it's a star. I want to put some stars over a map image.
The problem is that the star's image has a white backgroud and when I draw over the map the white background appears.
My method to draw the star is like this:
Graphics graphics = Graphics.FromImage(map);
Image customIcon = Image.FromFile("../../star.png");
graphics.DrawImage(customIcon, x, y);
I tried with transparent backgroud images (PNG and GIF formats), and it always draw something surrounding the star. How can I draw a star without its background?
The program is for Windows Mobile 5.0 and above, with Compact Framework 2.0 SP2 and C#.
I tried with this code:
Graphics g = Graphics.FromImage(mapa);
Image iconoPOI = (System.Drawing.Image)Recursos.imagenPOI;
Point iconoOffset = new Point(iconoPOI.Width, iconoPOI.Height);
System.Drawing.Rectangle rectangulo;
ImageAttributes transparencia = new ImageAttributes();
transparencia.SetColorKey(Color.White, Color.White);
rectangulo = new System.Drawing.Rectangle(x, y, iconoPOI.Width, iconoPOI.Height);
g.DrawImage(iconoPOI, rectangulo, x, y, iconoPOI.Width, iconoPOI.Height, GraphicsUnit.Pixel, transparencia);
But I don't see anything on map.
X and Y are de coordinates where I want to draw the iconoPOI which it's a PNG imagen with a white background.
Thank you!
One valid answer can be found here:
Answer
Thank you!
Normally this task is pretty complicated (you have to tap the windows API BitBlt function and create a black-and-white mask image and other stuff), but here's a simple way to do it.
Assuming you have one bitmap for your background image (bmpMap) and one for your star image (bmpStar), and you need to draw the star at (xoffset, yoffset), this method will do what you need:
for (int x = 0; x < bmpStar.Width; x++)
{
for (int y = 0; y < bmpStar.Height; y++)
{
Color pixel = bmpStar.GetPixel(x, y);
if (pixel != Color.White)
{
bmpMap.SetPixel(x + xoffset, y + yoffset, pixel);
}
}
}
SetPixel and GetPixel are incredibly slow (the preferred way is to use the bitmap's LockBits method - there are questions here on SO that explain how to use it), but this will get you started.

Glut glLoadMatrixf camera equivalent

In my glut application I'm simulating a plane with the camera. When the planes speed is low I intend to have the nose start to point towards the ground as the camera falls. My first instinct was to just change the pitch until it was pointed downwards at -90degrees. However I can't just change the pitch because if the plane is tilted on its side or upside down then it would note be changing direction towards the ground.
Now i'm trying to do a rough simulation of this by shifting the 'lookAt.y' downwards. To do this I am trying to get all the current camera coordinates that I use to set the camera
(eye.x, eye.y, eye.z, look.x, look.y, look.z, up.x, up.y, up.z). Then recall the set with the new modified values.
I've been working with the Camera.cpp and Camera.h to control my camera functions. They can be found here
after adding methods to get all the values, only the eye values are actually updated when various camera motions are made. I guess my question is how do I retrieve these values.
The glLoadMaxtrix call is in this function
void Camera :: setModelViewMatrix(void)
{ // load model view matrix with existing camera values
float m[16];
Vector3 eVec(eye.x, eye.y, eye.z);
m[0] = u.x; m[4] = u.y; m[8] = u.z; m[12] = -eVec.dot(u);
m[1] = v.x; m[5] = v.y; m[9] = v.z; m[13] = -eVec.dot(v);
m[2] = n.x; m[6] = n.y; m[10] = n.z; m[14] = -eVec.dot(n);
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1.0;
look.x = u.y; look.y = v.y; look.z = n.y;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m);
}
Is there a way to get 'eye', 'lookAt', and 'up' values from the matrix here? Or should I do something else to get these values?
-Thanks in advance for your help
The camera class you link to is not an actual OpenGL class, but it should be simple enough to work with.
The function quoted just takes the current values of the camera object and sends them to OpenGL. If you look at the camera's set function, you can see how the program calculates the values it actually stores.
The eye value is stored directly. The lookAt value is just the value of (eye - n), by vector math. The up value is the hardest, but if I remember my vector math correctly, I believe that up = (n cross u).