I'm not good in bit logic but I think it will be the best solution for my problem.
I have to find if an object can fit in a box, I won't consider 3D rotation but just simple 90° options.
So basically if the object can fit in any way inside the box.
I'm actually checking all the dimensions of the object against the dimensions of the box, so I know if ObjWidth can fit in BoxWidth OR BoxLength OR BoxHeight and so on with ObjLength and ObjHeight.
This is defined using a Flag enum for each dimension
enum En_Dimension
{
None = 0,
Width = 1,
Lenght = 2,
Height = 4,
All = Width | Length| Height,
}
So I can have (that means that it fit on that side):
width = Width | Length | Height /// 111
length = Width /// 001
height = Width /// 001
basically my method should be something like
bool FitIn (Size container)
{
En_Dimension width = En_Dimension.None;
En_Dimension length = En_Dimension.None;
En_Dimension height = En_Dimension.None;
for(var do in this.Dimensions){
for (var db in container.Dimensions){
if (do <= db) {
// already implemented code to
// SET width OR length OR height
}
}
}
/// EXAMPLES
/// 001 001
/// 110 001
/// 010 111
/// FIT DON'T FIT
return (/*width, length, height BIT LOGIC*/) == En_Dimension.All
}
The expected output of the example is false while it should return true only when it "fit" on all the lines in at least one not already fitted side.
Let's say this are the "valid" combination of ones
1** 1** *1* *1* **1 **1
*1* **1 1** **1 1** *1*
**1 *1* **1 1** *1* 1**
It could be done with 6 tests, corresponding to each of the permutations:
int fittingDims = (int)width | ((int)length << 4) | ((int)height << 8);
return (fittingDims & 0x124) == 0x124 ||
(fittingDims & 0x142) == 0x142 ||
(fittingDims & 0x214) == 0x214 ||
(fittingDims & 0x241) == 0x241 ||
(fittingDims & 0x412) == 0x412 ||
(fittingDims & 0x421) == 0x421;
There are no octal literals in C# so I used 4 bits per "block" to make the constants nice in hexadecimal.
Related
I want to change RGB values according to the percentage. means 0% should show Red , 50% should green and 100% will Blue color.I am working on fastled.I tried like this but didnt get the best result.can anyone suggest some good stuf??
int R,G,B;
int p = percentage;
if(p >= 0 and p <= 50){
R = abs(p - 100);
G = p*2;
}
if(p > 50 and p <= 100){
G = abs(p - 100);
B = p*2;
}
>! also tried
R = abs(p-100);
G = p/2;
B = p;
leds[0] = CRGB(R,G,B);
FastLED.show();
You need to convert percentage values to 8-bit binary values, i.e., convert values in the range [0,100] into values in the range [0,255] (which is [0x00,0xFF] in hex).
A simple scaling operation does this:
int r = pR * 255 / 100; // percentage red to hex
or equivalently:
int r = pR * 0xFF / 100; // percentage red to hex
The opposite conversion, from hex value to percentage, is just the reverse operation.
Note that since there are only 101 percentage values, you won't get all of the 256 possible 8-bit hex values when you do this conversion, but it should be close enough.
From your problem statement, you probably want something like this which generates RGB colors counter-clockwise around the sRGB color gamut from red to blue.
#include <array>
#include <string>
#include <cmath>
#include <iostream>
std::array<uint8_t, 3> getcolorpercent(double percent)
{
std::array<uint8_t, 3> rgb{};
int segment{static_cast<int>(percent/25)};
double percent_f = .01 * (percent - 25 * segment);
double col0{ 1 }, col1{ 1 };
if (segment % 2 == 0)
col1 = sqrt(4 * percent_f);
else
col0 = sqrt(1 - 4 * percent_f);
rgb[(segment / 2) % 3] = static_cast<uint8_t>(std::round(255*col0));
rgb[(1 + segment / 2) % 3] = static_cast<uint8_t>(std::round(255 * col1));
return rgb;
}
int main()
{
auto print = [](const std::array<uint8_t, 3> rgb, std::string descr) {
// note: 0+... is to convert uint8_t to int to precent interpreting as char
std::cout << descr << " red:" << 0+rgb[0] << " green:" << 0+rgb[1] << " blue:" << 0+rgb[2] << '\n';
};
std::array<uint8_t, 3> rgb_red = getcolorpercent(0);
std::array<uint8_t, 3> rgb_orange = getcolorpercent(15);
std::array<uint8_t, 3> rgb_yellow = getcolorpercent(25);
std::array<uint8_t, 3> rgb_cyan = getcolorpercent(75);
std::array<uint8_t, 3> rgb_violet = getcolorpercent(130);
print(rgb_red, "red=");
print(rgb_orange, "orange=");
print(rgb_yellow, "yellow=");
print(rgb_cyan, "cyan=");
print(rgb_violet, "violet=");
}
Output:
red= red:255 green:0 blue:0
orange= red:255 green:198 blue:0
yellow= red:255 green:255 blue:0
cyan= red:0 green:255 blue:255
violet= red:255 green:0 blue:228
This creates a (reversed) rainbow type from red to blue for 0% to 100%. Additionally, this has been expanded to allow percentages to exceed 100 which can be used to produces colors going from blue->violet->purple and back to red. Here's an image created from this going from percent 0 to 100:
I need to filter given width of lines in a image.
I am coding a program which will detect lines of road image. And I found something like that but can't understand logic of it. My function has to do that:
I will send image and width of line in terms of pixel size(e.g 30 pixel width), the function will filter just these lines in image.
I found that code:
void filterWidth(Mat image, int tau) // tau=width of line I want to filter
int aux = 0;
for (int j = 0; j < quad.rows; ++j)
{
unsigned char *ptRowSrc = quad.ptr<uchar>(j);
unsigned char *ptRowDst = quadDst.ptr<uchar>(j);
for (int i = tau; i < quad.cols - tau; ++i)
{
if (ptRowSrc[i] != 0)
{
aux = 2 * ptRowSrc[i];
aux += -ptRowSrc[i - tau];
aux += -ptRowSrc[i + tau];
aux += -abs((int)(ptRowSrc[i - tau] - ptRowSrc[i + tau]));
aux = (aux < 0) ? (0) : (aux);
aux = (aux > 255) ? (255) : (aux);
ptRowDst[i] = (unsigned char)aux;
}
}
}
What is the mathematical explanation of that code? And how does that work?
Read up about convolution filters. This code is a particular case of a 1 dimensional convolution filter (it only convolves with other pixels on the currently processed line).
The value of aux is started with 2 * the current pixel value, then pixels on either side of it at distance tau are being subtracted from that value. Next the absolute difference of those two pixels is also subtracted from it. Finally it is capped to the range 0...255 before being stored in the output image.
If you have an image:
0011100
This convolution will cause the centre 1 to gain the value:
2 * 1
- 0
- 0
- abs(0 - 0)
= 2
The first '1' will become:
2 * 1
- 0
- 1
- abs(0 - 1)
= 0
And so will the third '1' (it's a mirror image).
And of course the 0 values will always stay zero or become negative, which will be capped back to 0.
This is a rather weird filter. It takes the pixel values three by three on the same line, with a tau spacing. Let these values by Vl, V and Vr.
The filter computes - Vl + 2 V - Vr, which can be seen as a second derivative, and deducts |Vl - Vr|, which can be seen as a first derivative (also called gradient). The second derivative gives a maximum response in case of a maximum configuration (Vl < V > Vr); the first derivative gives a minimum response in case of a symmetric configuration (Vl = Vr).
So the global filter will give a maximum response for a symmetric maximum (like with a light road on a dark background, vertical, with a width less than 2.tau).
By rearranging the terms, you can see that the filter also yields the smallest of the left and right gradients, V - Vm and V - Vp (clamped to zero).
I am implementing an alpha blending, and one of the examples I came across used this format. I am confused why the division by 256 and why isn't there inv_alpha in red and blue channels
int pixel,vga_pixel;
int alpha, blue, green, red, pixel;
int height = 1296;
int width = 968;
int x, y;
for (y = 0; y <= height; y++){
for (x = 0; x <= width; x++){
pixel = *(img.memloc + x + y);
//0xff gets the first 8 bits, in this case red
red = pixel & 0xff;
//shift by 8 to get rid of red then AND to get first 8, here green
green = pixel >> 8 & 0xff;
blue = pixel >> 16 & 0xff;
alpha = pixel >> 24 & 0xff;
int inv_alpha = 0xff - alpha; // 1-alpha
int vga_red = (red*(int)alpha);
int vga_green = (green*(int)alpha + inv_alpha/256);
int vga_blue = (blue*(int)alpha);
int vga_alpha = 0xff;
int vga_pixel = vga_alpha << 24 | vga_blue << 16 | vga_green << 8 | vga_red;
}
}
Can anyone clarify if this is a valid method, and why?
It look's like you've mixed the formulas from integer and floating point blending. For example the vga_red should probably become 255 if both red and alpha is, so it would be closer to (red*alpha)/255, but probably you should probably ensure correct rounding by using (red*alpha+127)/255.
The dividing inv_alpha with 256 would always yield zero so it's probably wrong, I'd guess that you want the result to be green if alpha is 255 and 255 if alpha is 0. So it would become something like (green*alpha+127)/255 + inv_alpha.
The formula for alpha blending is C = alpha_A * A + (1 - alpha_A * B). But in this formula we're working with floating point values and alpha is a value between 0 and 1.
Since we're working with integer values the alpha (and red, green and blue as well) is a value between 0 and 255. So the value of 1 - alpha_A is encapsulated in inv_alpha_A = 255 - alpha_A.
Since each color may not exceed the maximum value of one byte we have to ensure that the calculated number does not exceed 255. So we have to divide by 255.This results in:
C = (alpha_A * A + inv_aplha_A * B) / 255
(I intentionally skipped the rounding problem).
I have a picture of 2600x2600 in gray.
Or it can be seen as a matrix of unsigned short.
I would like to find the darkest (or the brightest by computing the inverse picture) square are of a fixed size N. N could be parametrized (if there is more than one darkest square I would like all).
I read detection-of-rectangular-bright-area-in-a-image-using-opencv
but it needs to a threshold value I don't have and furthermore I search a fixed size.
Do anyone as a way to find it in c++ or python ?
For each row of the image,
Add up the N consecutive pixels, so you get W - N + 1 pixels.
For each column of the new image,
For each consecutive sequence of N pixels, (H - N + 1)
Add them up and compare to the current best.
To add up each consecutive sequence of pixels, you could subtract the last pixel, and add the next pixel.
You could also reuse the image array as storage, if it can be modified. If not, a memory-optimization would be to just store the latest column, and go trough it for each step in the first loop.
Runtime: O(w·h)
Here is some code in C#, to demonstrate this (ignoring the pixel format, and any potential overflows):
List<Point> FindBrightestSquare(int[,] image, int N, out int squareSum)
{
int width = image.GetLength(0);
int height = image.GetLength(1);
if (width < N || height < N)
{
return false;
}
int currentSum;
for (int y = 0; y < height; y++)
{
currentSum = 0;
for (int x = 0; x < width; x++)
{
currentSum += image[x,y];
if (x => N)
{
currentSum -= image[x-N,y];
image[x-N,y] = currentSum;
}
}
}
int? bestSum = null;
List<Point> bestCandidates = new List<Point>();
for (int x = 0; x <= width-N; x++)
{
currentSum = 0;
for (int y = 0; y < height; y++)
{
currentSum += image[x,y];
if (y >= N)
{
currentSum -= image[x, y-N];
if (bestSum == null || currentSum > bestSum)
{
bestSum = currentSum;
bestCandidates.Clear();
bestCandidates.Add(new Point(x, y-N));
}
else if (currentSum == bestSum)
{
bestCandidates.Add(new Point(x, y-N));
}
}
}
}
squareSum = bestSum.Value;
return bestCandidates;
}
You could increment the threshold until you find a square, and use a 2D FSM to detect the square.
This will produce a match in O(width * height * bpp) (binary search on the lowest possible threshold, assuming a power-of-two range):
- set threshold to its maximum value
- for every bit of the threshold
- clear the bit in the threshold
- if there is a match
- record the set of matches as a result
- else
- set the bit
- if there is no record, then the threshold is its maximum.
to detect a square:
- for every pixel:
- if the pixel is too bright, set its line-len to 0
- else if it's the first column, set its line-len to 1
- else set its line-len to the line-len of the pixel to the left, plus one
- if the pixel line-len is less than N, set its rect-len to 0
- else if it's the first row, set its rect-len to 1
- else set its rect-len to the rect-len of the pixel above, plus one
- if the rect-len is at least N, record a match.
line-len represents the number of consecutive pixels that are dark enough.
rect-len represents the number of consecutive rows of dark pixels that are long enough and aligned.
For video-capture, replace the binary search by a linear search from the threshold for the previous frame.
Obviously, you can't get better than theta(width/N * height/N) best case (as you'll have to rule out every possible position for a darker square) and the bit depth can be assumed constant, so this algorithm is asymptotically optimal for a fixed N. It's probably asymptotically optimal for N as a part of the input as well, as (intuitively) you have to consider almost every pixel in the average case.
So I've successfully access pixel data in a frame using the c++ frame access wrapper on the opencv webpage
template<class Frame>
class Frame_Data {
IplImage *imgp;
public:
Frame_Data (IplImage *img=0) {imgp = img;}
~Frame_Data () {imgp = 0;}
void operator=(IplImage *img) {imgp=img;}
inline Frame* operator[] (int rowIndex) {
return ((Frame*)(imgp->imageData + rowIndex*imgp->widthStep));
}
};
typedef struct {
unsigned char b,g,r;
} RgbPixel;
typedef struct {
float b,g,r;
} RgbPixelFloat;
typedef Frame_Data<RgbPixel> RgbImage;
Im then using 2 for loops to go through the frame pixel array such as:
for (int i = ymin; i < ymax; i++)
{
for (int j = xmin; j < xmax; j++)
{
int r = image[i][j].r;
int g = image[i][j].g;
int b = image[i][j].b;
So lets say I want to throw in an IF statement to check pixel data colors. I've seen some websites list them as stuff like
image[i][j].r=0xFF;
or if g < 0x20
Im not used to the hex looking values, i tried to look them up but can't find any refernece, im used to cvscalars, so what do these mean? Like what does 0x20 stand for? or what about 0xFF?
thanks
The range from 0x00 ... 0xFF that you are seeing is one byte which can hold a value between 0 and 255 which is how pixel color data is stored, generally in 3 or 4 bytes consisting of Red, Blue, Green and optionally Alpha.
The CvScalar is just a convenience container of 1, 2, 3 or 4 doubles which can be used to hold these values in a slightly different form.
For example:
cv.RGB(1.0, 0.5, 0.3) sets the red component of the color to 1.0 or 100%, the green component to 0.5 or 50% and the blue component to 0.3 or 30%. When the actual color structure is created each of these components will be made up of exactly one byte so this is analagous to setting the
R (red component) to 1.0 * 0xFF = 0xFF
G (green component) to 0.5 * 0xFF = 0x7F
B (blue component) to 0.3 * 0xFF = 0x26
The alpha is automatically set to 1.0 or 0xFF
Hexidecimal is just another representation of a number (base 16).
It's not too hard to get used to, you just need to learn how to convert to and from regular base 10 numbers.
Open up your favourite windows/mac calculator, switch to Hex mode, and type in FF. (the 0x prefix just tells the code that it's it's hexidecimal number)
Switch to Dec[imal] and the number will change to 255.
Type 32 in, in Decimal mode, then click hex, you'll see the number change to 20 (or 0x20 as it is in your code)
Now you can go from hexidecimal to decimal, you can go from decimal to scalar quite easily; Just convert the range;
float Scalar = static_cast<float>( Decimal ) / 255.f; // 255 being the largest value for your byte-colour
Enjoy Hex! You'll find it a very useful, neat and important way of looking at data.