Is there a c++ function or an opencv library that can calculate the average log of the luminance of a given 8*8 block or total image? My aim is to calculate the average luminance and store it back in the block. Also, is there another way to calculate the overall luminance or average luminance in another scientific method that fits the human visual system? If someone can point me to a lib or function in c++ I would appreciate that.
To calculate the average luminance of an 8x8 block, centred at each pixel in an input greyscale image, you could perform a 2D convolution of that image with an 8x8 kernel containing the value 1/64 i.e. 1/(8*8) in each cell.
This is referred to as a normalised box filter / box blur.
You can then sample the resulting image e.g. at (x,y) to yield the average luminance of the 8x8 block centred at (x,y).
There is code in the OpenCV manual for a normalised box filter, with user selectable size.
http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.html
Regarding the 'log' of this value, you can then use OpenCV function cvLog to take the log of the filtered image and obtain your result.
Related
I am new to opencv, coding in c++. I have a task given to me to decode a 2D circle barcode using an encoded array. I am up to the point where I am able to centralize the figure and get the line using Hough transforms.
Need help with how to read the colour in the images, note that each of the two adjacent blocks correspond to a letter.
Any pointers will be highly appreciated. Thanks.
First, you need to load the image. I suspect this isn't a problem because you are already using Hough transforms on it, but:
Mat img = imread(filename)
Once the image is loaded, you can grab any of the pixels using:
Scalar intensity = img.at<uchar>(y, x);
However, what you need to do is threshold the image. As I mentioned in the comments, the image colors are either 0 or 255 for each RGB channel. This is on purpose for encoding the data in case there are image artifacts. If the channel is above a certain color value, then you will consider that it's 'on' and if below, it's 'off'.
Threshold the image using adaptiveThreshold. I would threshold down to binary 1 or 0. This will produce RGB triplets that are one of eight (2^3) possible combinations, from (0,0,0) to (1,1,1).
Then you need to walk the pixels. This is where it gets interesting.
You say each adjacent 2 pixels form a single letter. That's 2^6 or 64 different letters. The next question is: are the letters arranged in scan lines, left-to-right, top to bottom? If yes, then it will be important to orientate the image using the crosshair in the center.
If the image is encoded radially (using polar coordinates) then things get a little trickier. You need to use cvLinearPolar to remap the image.
Otherwise you need to walk the whole image, stepping the size of the RGB blocks and discard any pixels whose distance from the center is greater than the radius of the circle. After reading all of the pixels into an array, group them by pairs.
At some point, I would say that using OpenCV to do this is heading towards machine learning. There has to be some point where you can cut in and use Neural Networks to decode the image for you. Once you have the circle (cutoff radius) and the image centered, you can convert to polar coordinates and discard everything outside the circle by cutting off everything greater than the radius of the circle. Remember, polar coordinates are (r,theta), so you should be able to cutoff the right part of the polar image.
Then you could train a Neural Network to take the polar image as input and spit out the paragraph.
You would have to provide lots of training data, and the trained model would still be reliant on your ability to pre-process the image. This will include any affine transforms in case the image is tilted or rotated. At that point you would say to yourself that you've done all the heavy lifting and the last little bit really isn't that hard.
However, once you get a process working for a clean image, you can start adding to steps to introduce ML to work on dirty images. HoughCircles can be used to detect the part of an image to run detection on. Next, you need to decide if the image inside the circle is a barcode or not.
A good barcode system will have parity bits or some other form of error correction, but you can use machine learning to cleanup output.
My 2 cents anyways.
So, what I am trying to do is to calculate the density profile (HU) along a trajectory (represented by target x,y,z and tangent to it) in a CT. At the moment, I am able to get the profile along a line passing through the target and at a certain distance from the target (entrance). What I would like to do is to get the density profile for a volume (cylinder in this case) of width 1mm or so.
I guess I have to do interpolation of some sort along voxels since depending on the spacing between successive coordinates, several coordinates can point to the same index. For example, this is what I am talking about.
Additionally, I would like to get the density profile for different shapes of the tip of the trajectory, for example:
My idea is that I make a 3 by 3 matrix, representing the shapes of the tip, and convolve this with the voxel values to get HU values corresponding to the tip. How can I do this using ITK/VTK?
Kindly let me know if you need some more information. (I hope the images are clear enough).
If you want to calculate the density drill tip will encounter, it is probably easiest to create a mask of the tip's cutting surface in a resolution higher than your image. Define a transform matrix M which puts your drill into the wanted position in the CT image.
Then iterate through all the non-zero voxels in the mask, transform indices to physical points, apply transform M to them, sample (evaluate) the value in the CT image at that point using an interpolator, multiply it by the mask's opacity (in case of non-binary mask) and add the value to the running sum.
At the end your running sum will represent the total encountered density. This density sum will be dependent on the resolution of your mask of the tip's cutting surface. I don't know how you will relate it to some physical quantity (like resisting force in Newtons).
To get a profile along some path, you would use resample filter. Set up a transform matrix which transforms your starting point to 0,0,0 and your end point to x,0,0. Set the size of the target image to x,1,1 and spacing the same as in source image.
I don't understand your second question. To get HU value at the tip, you would sample that point using a high quality interpolator (example using linear interpolator). I don't get why would the shape of the tip matter.
I have an OpenCV application and I have to implement a correspondence search using varying support weights between two image pair. This work is very similar to "Adaptive Support-Weight Approach for Correspondence Search" by Kuk-Jin Yoon and In So Kweon. The support weights are in a given support window.
I calculate dissimilarity between pixels using the support weights in the two images. Dissimilarity between pixel 'p' and 'Pd' is given by
where Pd and Qd are the pixels in the target image when pixels p and q in the reference image have a disparity value d; Np and Npd are the support weight.
After this, the disparity of each pixel is selected by the WTA (Winner-Takes-All) method as:
What I would like to know is how to proceed starting with the formula of the fig.1 (function computing dissimilarity and weights that I have written), i.e. which pixel to consider? Where to start? What pixel with? Any suggestion?
The final result of the work should be similar to:
What could be a good way to do it?
UPDATE1
Should I start creating a new image, and then consider the cost between the pixel (0,0) and all the other pixels, find the minimum value and set this value as the value in the new image at pixel (0,0) ? And so on with the other pixels?
I want to obtain all the pixels in an image with pixel values closest to certain pixels in an image. For example, I have an image which has a view of ocean (deep blue), clear sky (light blue), beach, and houses. I want to find all the pixels that are closest to deep blue in order to classify it as water. My problem is sky also gets classified as water. Someone suggested to use K nearest neighbor algorithm, but there are few examples online that use old C style. Can anyone provide me example on K-NN using OpenCv C++?
"Classify it as water" and "obtain all the pixels in an image with pixel values closest to certain pixels in an image" are not the same task. Color properties is not enough for classification you described. You will always have a number of same colored points on water and sky. So you have to use more detailed analysis. For instance if you know your object is self-connected you can use something like water-shred to fill this region and ignore distant and not connected regions in sky of the same color as water (suppose you will successfully detect by edge-detector horizon-line which split water and sky).
Also you can use more information about object you want to select like structure: calculate its entropy etc. Then you can use also K-nearest neighbor algorithm in multi-dimensional space where 1st 3 dimensions is color, 4th - entropy etc. But you can also simply check every image pixel if it is in epsilon-neighborhood of selected pixels area (I mean color-entropy 4D-space, 3 dimension from color + 1 dimension from entropy) using simple Euclidean metric -- it is pretty fast and could be accelerated by GPU .
im trying to create an image filter in OpenGL CE. currently I am trying to create a series of 4x4 matrices and multiply them together. then use glColorMask and glColor4f to adjust the image accordingly. I've been able to integrate hue rotation, saturation, and brightness. but i am having trouble adding contrast. thus far google hasn't been to helpful. I've found a few matrices but they don't seem to work. do you guys have any ideas?
I have to say, I haven't heard of using a 4x4 matrix to do brightness or contrast. I think of these operations as being done on the histogram of the image, rather than on a local per-pixel basis.
Say, for instance, that your image has values from 0 to 200, and you want to make it brighter. You can then add values to the image, and what is shown on the screen will be brighter. If you want to enhance the contrast on that image, you would do a multiplication like:
(image_value - original_min)/(original_max - original_min) * (new_max - new_min) + new_min
if you want your new min to be 0 and your new max to be 255, then that equation would stretch the contrast accordingly. The original_min and original_max do not have to be the actual min and max of the entire image, the could be the min and max of a subsection of the image, if you want to enhance a particular area and don't mind clipping values above or below your new_min/new_max.
I suppose if you already know your range and so forth, you could incorporate that formula into a 4x4 matrix to achieve your goal, but only after you've done a pass to find the min and max of the original image.
I would also make sure to uncouple the display of your image from your image data; the above operations are destructive, in that you'll lose information, so you want to keep the original and display a copy.