Does the second channel of a C2 image represent the alpha channel or do they just fill the gap between C1-C3,C4?
You are mistaking colorspaces with channels. For example you have a greyscale colorspace, which is represented with 1 channel. Then you have BGR with 3 channels, and BGRA with 4. Here the 4th channel is the Alpha value. OpenCV supports several types of colorspaces.
OpenCV is opened to your needs, in some cases you have a mat with 2 values per pixel, for example Dense Optical Flow results, which have a vector of movement of each pixel (x,y vector). You may even create a greyscale image with alpha value for whatever reason or algorithm you have... in this case it will be a CV_8UC2. However this is not a standard colorspace in OpenCV, and a lot of the algorithms have hard constraints on the color space so they may not work with this Mat type.
A cv::Mat can have more than 4 channels even (up to 512 the last time I checked, for more info check the constant CV_CN_MAX), but beware that this may not work with all of OpenCV functions and it will more like a container to your custom algorithms.
Related
I would like to compare videos. To compare the quality (Non blurry) by coding a C program. Someone told me to learn about DFT (Discrete Fourier Transform) for image analysis and to use a FFT or DFT tool to learn the difference between blurred vs detailed (non-blurry) copies of same image.
(copied from other question):
Lets say we have different files with different video quality, one is extremely clear, other is blurred, one is having rough colors. Compare all files basically frame by frame and report to the user which has better quality.
So can anyone help me with this ??
Let's say we have various files having different video quality:
one is extremely clear, other is blurred, one is having rough colors.
Compare all files basically frame by frame and report to the user which has better quality.
(1) Color Quality detection...
To check which has better color, you analyze the histograms of the test images. The histogram will be a count of how many pixels have intensity X. Where X is a number ranging between 0 up to 255 (because each red, green and blue channels each holds any of those 256 possible intensities).
There are many tutorials online about how to create a histogram since it's a basic task in computer graphics.
Generally it goes like:
First make 3 arrays (eg: hist_Red) to hold data for red, green and blue channels.
Break up (using FOR loop) each pixel into individual R/G/B channel components:
example:
temp_Red = this_pixel >> 16 & 0x0ff;
temp_Grn = this_pixel >> 8 & 0x0ff;
temp_Blu = this_pixel >> 0 & 0x0ff;
Then add +1 to that specific red/green/blue intensity in relevant histogram.
example:
hist_Red[ temp_Red ] += 1;
hist_Grn[ temp_Grn ] += 1;
hist_Blu[ temp_Blu ] += 1;
By adding the totals of red, green and blue, you will have total intensities of RGB in an array that could build charts like below. Check with image's array has most values to find image with better quality of colors:
(2) Detailed vs Blurred detection...
You can try using a convolution filter to detect blur in image. Give the filter a kernel (eg: a matrix). The matrix (3x3) shown below gives an edge-detect filter, where blurred images give less edges (therefore gives more black pixels).
Use logic to assume that: more black pixels EQuals a more blurred image (less detail).
You can read about convolutions here
Lode's Computer Graphics Tutorial: Image Filtering
Image Convolution with C/C++ code
PDF Image Manipulation: Filters and Convolutions
PDF Read page 10 onwards : Convolution filters
i don't understand when opencv documentation mention the term "channel" . Does it mean the channel as in digital image ? or it is something else ?
So as OpenCV is an image processing Library, So A given image can be assumed as 2D matrix with each element as a pixel. Now since there are various types of image formats like Gray, RGB or RGBA, etc. each format is different as to how many colors it(pixel) can support. For example the pixels of Gray image take values in range 0-255 so to represent each gray pixel we need single uchar value, so it has single channel, similarly the pixels of RGB image can take values from 0-16777216 and to represent each RGB pixel, we need 3 uchar values, (256^3 = 16777216), hence it is 3 channels, similarly RGBA has 4 channels, the last channel is used for storing the alpha(transparency) value.
I have a vector of Point2f which have color space CV_8UC4 and need to convert them to CV_64F, is the following code correct?
points1.convertTo(points1, CV_64F);
More details:
I am trying to use this function to calculate the essential matrix (rotation/translation) through the 5-point algorithm, instead of using the findFundamentalMath included in OpenCV, which is based on the 8-point algorithm:
https://github.com/prclibo/relative-pose-estimation/blob/master/five-point-nister/five-point.cpp#L69
As you can see it first converts the image to CV_64F. My input image is a CV_8UC4, BGRA image. When I tested the function, both BGRA and greyscale images produce valid matrices from the mathematical point of view, but if I pass a greyscale image instead of color, it takes way more to calculate. Which makes me think I'm not doing something correctly in one of the two cases.
I read around that when the change in color space is not linear (which I suppose is the case when you go from 4 channels to 1 like in this case), you should normalize the intensity value. Is that correct? Which input should I give to this function?
Another note, the function is called like this in my code:
vector<Point2f>imgpts1, imgpts2;
for (vector<DMatch>::const_iterator it = matches.begin(); it!= matches.end(); ++it)
{
imgpts1.push_back(firstViewFeatures.second[it->queryIdx].pt);
imgpts2.push_back(secondViewFeatures.second[it->trainIdx].pt);
}
Mat mask;
Mat E = findEssentialMat(imgpts1, imgpts2, [camera focal], [camera principal_point], CV_RANSAC, 0.999, 1, mask);
The fact I'm not passing a Mat, but a vector of Point2f instead, seems to create no problems, as it compiles and executes properly.
Is it the case I should store the matches in a Mat?
I am no sure do you mean by vector of Point2f in some color space, but if you want to convert vector of points into vector of points of another type you can use any standard C++/STL function like copy(), assign() or insert(). For example:
copy(floatPoints.begin(), floatPoints.end(), doublePoints.begin());
or
doublePoints.insert(doublePoints.end(), floatPoints.begin(), floatPoints.end());
No, it is not. A std::vector<cv::Pointf2f> cannot make use of the OpenCV convertTo function.
I think you really mean that you have a cv::Mat points1 of type CV_8UC4. Note that those are RxCx4 values (being R and C the number of rows and columns), and that in a CV_64F matrix you will have RxC values only. So, you need to be more clear on how you want to transform those values.
You can do points1.convertTo(points1, CV_64FC4) to get a RxCx4 matrix.
Update:
Some remarks after you updated the question:
Note that a vector<cv::Point2f> is a vector of 2D points that is not associated to any particular color space, they are just coordinates in the image axes. So, they represent the same 2D points in a grey, rgb or hsv image. Then, the execution time of findEssentialMat doesn't depend on the image color space. Getting the points may, though.
That said, I think your input for findEssentialMat is ok (the function takes care of the vectors and convert them into their internal representation). In this cases, it is very useful to draw the points in your image to debug the code.
I am unsure about this but I want to compute features around interest points computed by surf using RGB color Histogram. I guess the final feature will be 256 dimensional long. However, I am unsure if this is correct.
The dimension of the RGB color histogram is determined by how many bins you use for each channel. The dimension will be 24 (8+8+8) if you use 8 bins for each of them.
I'll be using OpenCV's cascade training functions.
But before that I need to prepare training data.
I just want to know if OpenCV can support it if my positive samples have transparency? Like for example if I want the classifier to learn how a vehicle looks, then can I supply positive sample images that have vehicles standing on a transparent background?
As mentioned in the comments above, the haar features are only computed on the grayscale image. This might pose a problem as you mentioned, when the default color of 0 might cause the "wheels" to lose contrast. You can probably "standardize" the transparent color rather than have it default to 0.
The first thing is you can load in all 4 channels (including your alpha channel) and then use the alpha channel to set the transparent part to a certain value.
Python version
I = cv2.imread("image.jpg", cv2.CV_LOAD_IMAGE_UNCHANGED)
alpha = I[:, :, 3]
G = cv2.cvtColor(I, cv2.COLOR_BGRA2GRAY)
G[alpha == 0] = 125 # Set transparent region to 125. Change to suit your needs.
C++
vector<cv::Mat> channels;
cv::split(I, channels);
cv::Mat alpha = channels[3];
alpha = 255 - alpha; // Invert mask so we select the transparent regions.
cv::Mat G = cv::cvtColor(I, cv::COLOR_BGRA2GRAY);
G.setTo(cv::Scalar(125), alpha);
As a note of caution, I think you might have to be careful about some of the operations above, e.g., loading image with alpha and "alpha = 255 - alpha;". I believe they are only available only in later versions of OpenCV. I'm using OpenCV 2.4.7 and it works (for the python version. I haven't tried the C++ but it should be the same). So if things don't work, check whether these operations are supported for your version of OpenCV. If not there are ways to get round them.