OpenCV - How to detect marker with alpha channel - c++

I want to detect custom forms like crosses.
I tried to use matchTemplate, but the background color of the marker is not always the same.
If I use a alpha channel in a marker png, I don't get a good result.
Maybe I have to set up a ROI?
What is a good way to detect this forms?

Have you considered using another color space where foreground and background are better separated?
use grayscale version if your markers are typically brighter than background
convert to HSV space and then only use Saturation and Value, e.g. if you have white markers on colored background
matchTemplate() does not work with a mask ("foreground-only" template).

Related

extracting part of an image outlined with a red box with OpenCV (C++)

I have the following image example image
I need to recognize the Character within it. To do this i want to produce a mask to remove everything but the red box.
What is the best method i could use to do this?
Currently I use a hsv filter to produce a mask, and use the mask to crop the image to just the red square.
cvtColor(src, HSV, COLOR_BGR2HSV);
inRange(HSV, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), HSVmask);
src.copyTo(src2, HSVmask);
This produces a poor mask as it has the T itself excluded depending on how i view the image, i need a more robust approach.
-I was wondering if there is a way to make a box around the significant white region and use the box as my mask instead, however i'm not sure on how to implement that on opencv.
With the mask i apply a canny edge detection, then i find the contours and fill the contours.
My results
Contour Output and Mask
The result i get isn't robust enough, i ideally need to be able to detect a large sign on a grass field from an aerial video feed, so it needs to work with the red square with different sizes.
Is there any way in which i can improve this process in general?
The character recognition method hasn't been decided yet.
If you just want to recognize the character
Convert image to gray scale.
Since the character is white and rest of image is colored, the character in the gray image will still be white. So take a threshold and suppress all non white pixels.
Run your classifier to recognize the character.
If you want to extract the red box
Locate the red pixels, then crop image.

Create mask to select the black area

I have a black area around my image and I want to create a mask using OpenCV C++ that selects just this black area so that I can paint it later. How can i do that without affecting the image itself?
I tried to convert the image to grayscale and then using threshold to convert it to binary, but it affects my image since the result contains black pixels from inside the image.
Another Question : if i want to crop the image instead of paint it, how can i do it??
Thanks in advance,
I would solve the problem like this:
Inverse-binarize the image with a threshold of 1 (i.e. all pixels with the value 0 are set to 1, all others to 0)
use cv::findContours to find white segments
remove segments that don't touch image borders
use cv::drawContours to draw the remaining segments to a mask.
There is probably a more efficient solution in terms of runtime efficiency, but you should be able to prototype my solution quite quickly.

Transparent pixels in OpenCV C++ (when using GrabCut)

I am using OpenCV 's implementation of GrabCut in order to remove the background from images. But for now the new background is black. Is there any way to make it transparent?
For now this part of the code looks like this:
Mat binMask( image.size(), CV_8UC1 );
binMask = mask & 1;
image.copyTo( result, binMask );
Can I somehow fill the binMask with transparent pixels?
I've read some tutorials for overlaying images, but I don't need a transparent image in front of my picture but behind.
I hope someone could help.
Many thanks!
Since you are using a 8UC1 image type, it's not possible to have transparent pixels.
These are allowed only if you have an alpha channel, with alpha set to 0: you must use a 4-channel image (3 for colors, 1 for alpha channel). The alpha channel is supported in file formats such as PNG, but not in JPG.
In case of masking, you don't need by the way the usage of transparent pixels, since the black ones actually correspond to 0 and they don't influence the result when you're blending two images (addWeighted for example, or also in case of bitwise_or operation).

transparent colour being shown some of the time

I am using a LPDIRECT3DTEXTURE9 to hold my image.
This is the function used to display my picture.
int drawcharacter(SPRITE& person, LPDIRECT3DTEXTURE9& image)
{
position.x = (float)person.x;
position.y = (float)person.y;
sprite_handler->Draw(
image,
&srcRect,
NULL,
&position,
D3DCOLOR_XRGB(255,255,255));
return 0;
}
According to the book I have the RGB colour shown as the last parameter will not be displayed on screen, this is how you create transparency.
This works for the most part but leaves a pink line around my image and the edge of the picture. After trial and error I have found that if I go back into photoshop I can eliminate the pink box by drawing over it with the pink colour. This can be see with the ships on the left.
I am starting to think that photoshop is blending the edges of the image so that background is not all the same shade of pink though I have no proof.
Can anyone help fix this by programming or is the error in the image?
If anyone is good at photoshop can they tell me how to fix the image, I use png mostly but am willing to change if necessary.
edit: texture creation code as requested
character_image = LoadTexture("character.bmp", D3DCOLOR_XRGB(255,0,255));
if (character_image == NULL)
return 0;
You are loading a BMP image, which does not support transparency natively - the last parameter D3DCOLOR_XRGB(255,0,255) is being used to add transparency to an image which doesn't have any. The problem is that the color must match exactly, if it is off even by only one it will not be converted to transparent and you will see the near-magenta showing through.
Save your images as 24-bit PNG with transparency, and if you load them correctly there will be no problems. Also don't add the magenta background before you save them.
As you already use PNG, you can just store the alpha value there directly from Photoshop. PNG supports transparency out of the box, and it can give better appearance than what you get with transparent colour.
It's described in http://www.toymaker.info/Games/html/textures.html (for example).
Photoshop is anti-aliasing the edge of the image. If it determines that 30% of a pixel is inside the image and 70% is outside, it sets the alpha value for that pixel to 70%. This gives a much smoother result than using a pixel-based transparency mask. You seem to be throwing these alpha values away, is that right? The pink presumably comes from the way that Photoshop displays partially transparent pixels.

Recoloring an image based on current theme?

I want to develop a program which recolors the input image based on the given theme the same way as ms-powerpoint application does.
I am giving following link that shows what exactly i want to do.
I want to generate images same as images in below link under the Dark Variations and light Variations title based on the current theme.
http://blogs.msdn.com/powerpoint/archive/2006/07/06/658238.aspx
Can anybody give me idea,info regarding how to achieve it efficiently ??
You can give a look to the HSL colorspace to be able to have the same result. HSL means Hue, Saturation, Lightness.
You can keep the lightness of each pixel of your image and change only the hue. I think this will allow you to achieve what you want. You can find the RGB to HSL conversion on the wiki page.
Hope that helps.
Step 1: Choose the colors you want to represent black and white. For the dark variations, choose black and a light color; for the light variations, choose a dark color and white.
Step 2: Convert a pixel to gray. A common formula for this is L = R*0.3 + G*0.59 + B*0.11.
Step 3: Interpolate between the colors using the gray value. output.R = (L/255)*light.R + (1-(L/255))*dark.R and likewise for green and blue.
You can use a library like CxImage and convert the image to grayscale, then use the mix command with another image that you have made that is the same size as the original, and mix the two with the Mix command, using the filters. You can do mix-screen, and this should tint the pixels the color of the second image in the resultant image. Try playing with CxImage a bit, see if it will do what you want it to do. This is all coming off the top of my head, and its been a while since I have tried to do anything like this. YMMV, but this would be the simplest implementation. You could always look at how CxImage does the blend, and apply it to the image yourself.
I must say thanks to Mark and Patrice for ur guidance which helped me achieved it.
For light variation, I have done it by converting the theme colors to HSV colorspace and found relation between output color and theme color for black color (input) .
The relation was found to be linear for saturation and value and hue was almost constant.
I have used interpolation formula to make it generic for any given theme.
I have also make use of color matrix to achieve desired result.
Similarly for dark variation i have used white color as input and apply the same technique.