How to find out straight lines in a image - c

I have an image file.(jpg or png)
This is having only 4 colors and few black lines.(600px X 600px image size).
There can be 2 or 4 or 6 black lines.
I need to get the (x1, y1) and (x2, y2) of each black lines.
Can be implemented with perl or c or matlab

Try applying the Hough Transform. It is especially effective at detecting lines.

One simple possibility to detect lines in images is calculating the image gradient.
For that calculate the gradient in either x or y direction (depending on the orientation of the lines) and then threshold the gradient to find out whether a black line is present.

Related

How to identify real red pixels?

I'm wirtting a program that changes all the image pixels to grayscale except for the red ones. At first, i thought it would be easier, but I'm having trouble trying to find the best way to determine if a pixel is red or not.
The first method I tried was a formula: Green < Red/2 && Blue < Red/1.5
results:
michael jordan
goldhill
Michael Jordan's image shows some not red pixels that pass the formula, like #7F3222 and #B15432. So i tried a different method, hue >= 345 || hue <= 9, trying to limit only the red part of the color wheel.
results:
michael jordan 2
goldhill 2
Michael Jordan's image now has less not red pixels and goldhill's image has more red pixels than before but still not what I want.
My methods are incorrect or just some adjustments are missing? if they're incorrect, how can I solve this problem?
Your question "How to identify 'real' red pixels", begs the question "what a red pixel actually is, especially if it has to be 'real'".
The RGB (red, green, blue) color model is not well suited to answer that question, therefore you should use the HSV (hue, saturation, value) model.
Hue defines the color in degrees (0 - 360 degrees)
Saturation defines the intensity of the color (0 - 100 %)
Value or Brightness defines the luminosity (0 - 100 %)
Steps:
convert RGB to HSV
if the H value is not red (+/- 30 degrees, you'll have to define a threshold range of what you consider to be red, 'real' red would be 0 degrees)
set S to 0 (zero), by doing so we remove the saturation of the color, which results in a gray shade
leave the brightness (V) as it is (or play around with it and see how it effects the results)
convert HSV to RGB
Convert from RGB to HSV and vice versa:
RGB to HSV
HSV to RGB
More info on HSV:
https://en.wikipedia.org/wiki/HSL_and_HSV
"All cats are gray in the dark"
Implement a dynamic color range. Adjust the 'red' range based on the brightness and/or saturation of the current pixel. Put a weight scale (on how much they affect the range in %) on the saturation and brightness values to determine your range ... play around to achieve the best results.
You used RGB, and HSV method, which it is good, and both are ok.
The problem is about defining red. Hue (or R) is not enough: it contains many other colours (in the broader sense): browns are dark/unsaturated reds (or oranges). Pink is also a tint of red (so red + white, so unsaturated).
So in your first method, I would add a condition: R > 127 (you must check yourself a good threshold). And possibly change the other conditions with a higher ratio of R to G and B and possibly adding also the ration R to (G+B). The first new added condition is about reds (and not "dark reds/browns), and brightness. Your two conditions are about "hue" (hue is defined by the top two values), and the last condition I wrote is about saturation.
You can do in a similar way for HSV: filter H (as you did), but you must filter also V (you want just bright reds), and also an high saturation, so you must filter all channels.
You should test yourself the saturation levels. The problem is that eyes adapt quickly to colours, so some images with a lot of redish colours are seen normally (less redish) by humans, but more red by above calculation. Etc. (so usually for such works there is some sliders to modify, e.v. you can try to automatize, but you need to find overall hue and brightness of image, and possibly complex methods, see CIECAM).

Making Width and Height of a character in console equal in terms of pixels (C)

I'm making a program in C (simple snake game).
I'm using window.h and came across an inconvenience.
I'm using COORD's and SetConsoleCursorPosition to move about the cursor.
However, moving one y coordinate is almost the same as moving two x coordinates in terms of how many pixels each represents.
For example, this square window has a width of 80 and height of 40 in terms of the cursor position coordinates.
Also, you can clearly see the contraction (and therefore reduction of apparent speed of the snake) when moving sidewards in the images below.
Is there any efficient solution to this so that the pixel size of one move in the x direction is the same as one move in the y direction.
Many thanks.
[
The SetCurrentConsoleFontEx function lets you specify the console font size in the lpConsoleCurrentFontEx's dwFontSize member. There you can set the font width and height be the same.

Blending text, rendered by FreeType in color and alpha

I am using FreeType to render some texts.
The surface where I want to draw the text is a bitmap image with format ARGB, pre-multiplied alpha.
The needed color of the text is also ARGB.
The rendered FT_Bitmap has format FT_PIXEL_MODE_LCD - it is as the text is rendered with white color on black background, with sub-pixel antialiasing.
So, for every pixel I have 3 numbers:
Da, Dr, Dg, Db - destination pixel ARGB (the background image).
Fr, Fg, Fb - FreeType rendered pixel (FT_Bitmap rendered with FT_RENDER_MODE_LCD)
Ca, Cr, Cg, Cb - The color of the text I want to use.
So, the question: How to properly combine these 3 numbers in order to get the result bitmap pixel.
The theoretical answers are OK and even better than code samples.
Interpet the FreeType data not as actual RGB colors (these 'raw' values are to draw text in black) but as intensities of the destination text color.
So the full intensity of each F color component is F*C/255. However, since your C also includes an alpha component, the intensity is scaled by it:
s' = F*C*A/(255 * 255)
assuming, of course, that F, C, and A are inside the usual range of 0..255. A is a fraction A/255, and the second division is to bring F*C back into the target range. s' is now the derived source color.
On to plotting it. Per color component, the new color gets add to D, and D in turn gets dimished by the source's alpha 255-A (scaled).
That leads to the full sum
D' = D*(255-A)/255 + F*C*A/(255 * 255)
equal to (moving one value to the right)
D' = (D*(255-A) + F*C*A/255)/255
for each separate channel r,g,b of D, F, C and A. The last one, alpha, also needs a separate calculation for each channel because your FreeType output data returns this format.
If the calculation is too slow, you could compare the visual result with not-LCD-optimized grayscale output from FreeType. I suspect that especially on 'busy' (not entirely monochrome) backgrounds the extra calculations are simply not worth it.
The numerical advantage of a pure grayscale input is that you only have to calculate A and 1-A once for each triplet of RGB colors.
The "background" also has an alpha channel but to draw text "on" it you can regard this as 'unused'. Drawing a transparent item onto another transparent item does not, in general, change its intrinsic transparency.
After some discovery, I found the right answer. It is disappointing.
It is impossible to draw subpixel rendered graphics (including fonts) on a transparent image with RGBA format.
In order to properly render such graphics, a format that supports separate alpha channels for every color is mandatory.
For example 48 bit per pixes: RrGgBg where r, g and b are the alpha channels for the red, green and blue collor channels respectively.

Two questions about SOIL, OpenGL and GLUT

Two questions about these three:
How can you load only a PART of an image in a texture (GLuint) using SOIL. I can load a full PNG picture but I can't figure out how to load only a PART of it. As in animations. for example HERE which is an animation of a shooting catapult. How do I load only a part of it ? (With known location of pixels needed for that part).
How to do Pixel-per-pixel collision detection using glReadPixels();? I succeeded using the function to read pixels off the screen but I'm not sure when to use it. First I thought about when loading a texture, analyze its limits (the pixels that might collide and not all the pixels) into a certain pattern and then when a grid of a certain PNG crosses another - analyze if the pixels of both textures in the certain X and Y are meant to be touching each other and colliding. I'm not sure how to do that (using glReadPixels or any other function to read pixels off of the PNG texture which ISN'T on screen yet). Any idea to make Pixel-per-pixel 2D collision ? OR a better 2D collision detection algorithm ?
1) To read only part of an image as a texture, one method is to read the entire image and load it into a texture. You can then create a new texture using the glTexSubImage2D() call. This is particularly convenient for sprites because you can call it repeatedly, changing the x and y offset to pull out the different frames of your animation.
2) Collision detection is a big topic and too broad to answer in a single question like this. You should look up QuadTrees (or if you're working in 3D, KdTrees). They partition the space so you can compare the bounding boxes of your various sprites efficiently. Once you find 2 sprites whose bounding boxes overlap, you can test them more closely to see if they overlap. Usually you can use some trick such as blitting their 1-bit masks to the same small texture (with the proper relative offsets) using an AND-like blend mode (where the output is 1 only when both inputs are 1) and seeing if any pixels in the resulting texture are turned on. That way you're only scanning an area that is at most the size of the 2 textures, and not the entire window.
To expand on what I'm trying to describe above with the AND-like blend mode, you have the following scenario:
2 1-bit sprite masks where each pixel is 0 if the sprite does not cover that pixel and 1 if it does. These are the input textures.
1 1-bit output texture where the 2 sprites will be drawn
For each pixel of the output, you have 4 possibilities for the inputs:
0-0 : both sprites are transparent at this output pixel, so they
don't touch here
1-0, 0-1: One sprite is transparent at this pixel,
the other is not. Hence, they don't overlap
1-1 : Both sprites are solid at this output pixel, so there's a
collision
If you write it as a truth table, it's the same as ANDing the 2 masks:
| 0 | 1 |
--+---+---+-
0 | 0 | 0 |
--+---+---+-
1 | 0 | 1 |
--+---+---+-

OpenGL Rotate an Object around It's Local Axes

Imagine a 3D rectangle at origin. It is first rotated along Y-axis. So good so far. Now, it is rotated around X-axis. However, OpenGL (API: glrotatef) interprets the X-axis to be the global X-axis. How can I ensure that the "axes move with the object"?
This is very much like an airplane. For example, if yaw (Y rotation) is applied first, and then pitch (X-rotation), a correct pitch would be X-rotation along the plane's local axes.
EDIT: I have seen this called gimbal lock problem, but I don't think it is though.
You cannot consistently describe an aeroplane's orientation as one x rotation and one y rotation. Not even if you also store and one z rotation. That's exactly the gimbal lock problem.
The crux of it is that you have to apply the rotations in some order. Say it's x then y then z for the sake of argument. Then what happens if the x rotation is by 90 degrees? That folds the y axis onto where the z axis was. Then say the y rotation is also by 90 degrees. That's now bent the z axis onto where the x axis was. So now what effect does any z rotation have?
That's just an easy to grasp example. It's not a special case. You can't wave your hands out of it by saying "oh, I'll detect when to do z rotations first" or "I'll do 90 degree rotations with a special pathway" or any other little hack. Trying to store and update orientations as three independent scalars doesn't work.
In classic OpenGL, a call to glRotatef means "... and then rotate the current matrix like this". It's not relative to world coordinates or to model coordinates or to any other space that you're thinking in.

Resources