When I look at Caffe's examples, they seem to always swap channels.
What is the reason behind it ?
Below is an exmaple taken from Caffe classification example:
transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension
transformer.set_mean('data', mu) # subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255]
transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR
This is a very annoying feature caffe got from opencv. It appears as if opencv reads color images, by default, in BGR format.
Related
For each pixel in an RGB image, I want to increase its brightness so that the strongest channel of that pixel (R, G, or B) is maximized. For example, if a pixel has an RGB value of (128, 64, 32), and the maximum channel value is 255, then that pixel should be changed to approximately (255, 128, 64). This is sort of a poor man's shadow removal system.
I can do this by iterating the pixels explicitly, but that is very inefficient. What is the most efficient way to do this by using strictly OpenCV methods? It seems it might use YUV space?
(By the way, I am using C# with EmguCV, but a straight Python/OpenCV answer would be fine. EDIT: But I can't use Python libraries)
In Python, OpenCV images are just numpy array. So here's a python/numpy approach:
# toy sample
np.random.seed(1)
a = np.random.randint(0, 100, (4,4,3), dtype=np.uint8)
# get max values across channels, scaled by 255
maxx = np.max(a, axis=-1)/255
# scale a by maxx
a = (a / maxx[:,:, None]).astype(np.uint8)
Input (with plt.imshow() so in rgb):
Output:
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.
I have a problem with normalization.
Let me what the problem is and how I attempt to solve it.
I take a three-channel color image, convert it to grayscale and apply uniform or non-uniform quantization and the same thing.
To this image, I should apply the normalization, but I have a problem even if the image and grayscale and always has three channels.
How can I apply normalization having a three-channel image?
Should the min and the max all be in the three channels?
Could someone give me a hand?
The language I am using is processing 2.
P.S.
Can you do the same thing with a color image instead use a grayscale image?
You can convert between the 1-channel and 3-channel representations easily. I'd recommend scikit-image (http://scikit-image.org/).
from skimage.io import imread
from skimage.color import rgb2gray, gray2rgb
rgb_img = imread('path/to/my/image')
gray_img = rgb2gray(rgb_image)
# Now normalize gray image
gray_norm = gray_img / max(gray_img)
# Now convert back
rgb_norm = gray2rgb(gray_norm)
I worked with a similar problem sometime back. One of the good solutions to this was to:
Convert the image from RGB to HSI
Leaving the Hue and Saturation channels unchanged, simply normalize across the Intensity channel
Convert back to RGB
This logic can be applied accross several other image processing tasks, like for example, applying histogram equalization to RGB images.
I have images containing gray gradations and one another color. I'm trying to convert image to grayscale with opencv, also i want the colored pixels in the source image to become rather light in the output grayscale image, independently to the color itself.
The common luminosity formula is smth like 0.299R+0.587G+0.114B, according to opencv docs, so it gives very different luminosity to different colors.
I consider the solution is to set some custom weights in the luminosity formula.
Is it possible in opencv? Or maybe there is a better way to perform such selective desaturation?
I use python, but it doesnt matter
This is the perfect case for the transform() function. You can treat grayscale conversion as applying a 1x3 matrix transformation to each pixel of the input image. The elements in this matrix are the coefficients for the blue, green, and red components, respectively since OpenCV images are BGR by default.
im = cv2.imread(image_path)
coefficients = [1,0,0] # Gives blue channel all the weight
# for standard gray conversion, coefficients = [0.114, 0.587, 0.299]
m = np.array(coefficients).reshape((1,3))
blue = cv2.transform(im, m)
So you have custom formula,
Load source,
Mat src=imread(fileName,1);
Create gray image,
Mat gray(src.size(),CV_8UC1,Scalar(0));
Now in a loop, access BGR pixel of source like,
Vec3b bgrPixel=src.at<cv::Vec3b>(y,x); //gives you the BGR vector of type cv::Vec3band will be in row, column order
bgrPixel[0]= Blue//
bgrPixel[1]= Green//
bgrPixel[2]= Red//
Calculate new gray pixel value using your custom equation.
Finally set the pixel value on gray image,
gray.at<uchar>(y,x) = custom intensity value // will be in row, column order
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.