I'm using OpenCV v4.4.0 with gcc v10.1 on Ubuntu 18.04.5. This code snippet:
using namespace std;
using namespace cv;
using namespace cv::viz;
......
vector<Vec3f> points{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
vector<int> faces{4, 0, 1, 2, 0, 4, 0, 2, 3, 0, 5, 1, 4, 5, 2, 1};
Viz3d window("Mesh");
WMesh mesh(points, faces);
window.setBackgroundColor(Color::gray());
mesh.setColor(Color::indigo());
mesh.setRenderingProperty(OPACITY, 0.4);
mesh.setRenderingProperty(SHADING, SHADING_FLAT);
mesh.setRenderingProperty(REPRESENTATION, REPRESENTATION_SURFACE);
window.showWidget("mesh", mesh);
window.spin();
creates and displays this planar mesh:
The square on the left is defined as 2 triangles and is shaded uniformly, but the square on the right, which is defined as a single quadrilateral face is not shaded uniformly. Again, the mesh is planar. Why the non-uniformity?
It becomes even more non-uniform when I change shading from SHADING_FLAT to SHADING_GOURAUD:
Can someone explain what is going on here? I know that quadrilateral faces are converted to triangles, but why the shading is non-uniform?
EDIT
As noted by Матвей Вислоух in his answer below, I intended to use:
vector<int> faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 5, 2};
which properly defines two triangular and one quadrilateral face. This solves the problem of artifacts in the left half, but they still remain in the right half:
vector<int> faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 2, 5};
There is a specific rule how opencv unpacks indices from polygon.
if there is a polygon : (5, 1, 4, 5, 2, 0) it consists of 3 triangles: (1,4,5) , (4, 5, 2), (5, 2, 0)
OLD:
vector faces{4, 0, 1, 2, 0, 4, 0, 2, 3, 0, 5, 1, 4, 5, 2, 1};
This means you draw 3 polygons: 2 quads and 1 pentagon.
But by indices I guess that you want to draw 2 triangles, and one quad, so try this:
vector faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 5, 2};
This question already has answers here:
How to fill OpenCV image with one solid color?
(9 answers)
Closed 4 years ago.
I am new in OpenCV. I have a image what I want is to change the color of each and every pixel of image with any single color.
I found that code but when I run this part of code then a exception is generated.
for (i = 0;i < img1.rows;i++) {
for (j = 0;j < img1.cols;j++) {
img1.at<Vec3b>(i, j) = Vec3b(255, 105, 240);
}
}
Can anyone please tell me the solution.
Or what I found is that this take a lot of time for the conversion So if their is any other approach then please tell me.
// Make a 3 channel image
cv::Mat img(480,640,CV_8UC3);
// Fill entire image with cyan (blue and green)
img = cv::Scalar(255,255,0);
You can use Mat::operator() to select the roi and then assign a value to it.
void main()
{
cv::Mat img = cv::Mat::ones(5, 5, CV_8UC3);
img({2, 4}, {2, 4}) = cv::Vec3b(7, 8, 9);
cout << img;
}
This will print
[ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0;
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0;
1, 0, 0, 1, 0, 0, 7, 8, 9, 7, 8, 9, 1, 0, 0;
1, 0, 0, 1, 0, 0, 7, 8, 9, 7, 8, 9, 1, 0, 0;
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0]
To fill image with single color, use rectangle with CV_FILLED argument.
(there might be some reasons for exception - image was not created, wrong pixel format etc - it is hard to diagnose a problem with given information)
I have a function PI (input 0 or 1), which gives PI[0] = -1, PI[1] = 1.
Given a byte B, I would like to have a function computing the minimum excess over PI from left to right. Similarly, I need a function computing the maximum excess over PI from left to right. Example:
PI_MIN[0] = -8, PI_MAX[0] = -1
PI_MIN[1] = -7, PI_MAX[1] = -1
PI_MIN[2] = -6, PI_MAX[2] = -1
PI_MIN[3] = -6, PI_MAX[3] = -1
At the moment I precompute the function values, store these in a universal table, and access it at runtime. Or alternatively I compute the result naively (for loop over bits). For PI_MIN and PI_MAX we have:
static constexpr int8_t PI_MIN[] { -8, -7, -6, -6, -6, -5, -5, -5, -6, -5, -4, -4, -4, -4, -4,
-4, -6, -5, -4, -4, -4, -3, -3, -3, -4, -3, -3, -3, -3, -3, -3, -3, -6, -5, -4, -4, -4, -3, -3, -3, -4, -3, -2, -2,
-2, -2, -2, -2, -4, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -6, -5, -4, -4, -4, -3, -3, -3, -4,
-3, -2, -2, -2, -2, -2, -2, -4, -3, -2, -2, -2, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -4, -3, -2, -2, -2, -1,
-1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -6, -5, -4,
-4, -4, -3, -3, -3, -4, -3, -2, -2, -2, -2, -2, -2, -4, -3, -2, -2, -2, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1,
-4, -3, -2, -2, -2, -1, -1, -1, -2, -1, 0, 0, 0, 0, 0, 0, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, -3,
-2, -2, -2, -1, -1, -1, -2, -1, 0, 0, 0, 0, 0, 0, -2, -1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -2, -1, 0, 0, 0,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static constexpr int8_t PI_MAX[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1, 2, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1,
2, 0, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 2, 2, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0,
1, 2, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 3, 4, 3, 3, 3, 4, 4,
4, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 3, 4, 3, 3, 3, 4, 4, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 3, 4, 3, 3, 3, 4, 4, 4, 5, 6, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 4, 4, 4, 5, 6, 4, 4,
4, 4, 4, 4, 5, 6, 5, 5, 5, 6, 6, 6, 7, 8 };
Unfortunately I couldn't find a pattern for all functions I need to use (e.g. PI_MIN, PI_MAX, but there is more). The question is: how can I find out whether a function exists which can compute this in a non-naive way (i.e., no for loop from left to right in the input byte). My goal is to reach maximum performance, since this function is in the inner-most loop of a larger program.
I'm thankful for any hints!
A non-branching version of pi_min (assuming the loop is unrolled).
/*
Calculate:
min(
pi(b7),
pi(b7)+pi(b6),
pi(b7)+pi(b6)+pi(b5),
pi(b7)+pi(b6)+pi(b5)+pi(b4),
pi(b7)+pi(b6)+pi(b5)+pi(b4)+pi(b3),
pi(b7)+pi(b6)+pi(b5)+pi(b4)+pi(b3)+pi(b2),
pi(b7)+pi(b6)+pi(b5)+pi(b4)+pi(b3)+pi(b2)+pi(b1),
pi(b7)+pi(b6)+pi(b5)+pi(b4)+pi(b3)+pi(b2)+pi(b1)+pi(b0))
Where,
pi(b) = b ? 1 : -1
and bits in byte b are numbered with the least significant bit (LSB) as 0.
This problem is essentially one of counting leading zeros where a string
of leading zeros may be interrupted by a one if it is eventually followed
by a zero. What happens if there are no leading zeros, then the count is -1.
The algorithm uses two stacks, "c0" and "c1". c0 is the leading zero count
and c1 is a stack of potentially intervening 1's.
foreach bit (following 4 cases are mutually exclusive, only 1 will execute)
0: if the '1' stack is empty => push a '0' onto the '0' stack
0: if the '1' stack is not empty => pop a '1'
1: if the first bit is a '1' => put the '0' stack in underflow state
1: if it is not the first bit => push a '1' onto the '1' stack
return -c0 because zeros actually count as -1
*/
int pi_min(uint8_t byte) {
int c0 = 0;
int c1 = 0;
for (int i = 0; i < 8; ++i) {
uint8_t b = !!(byte & (1 << (7-i)));
c0 -= (b & (i == 0));
c0 += ((!b) & (0 >= c1));
c1 -= ((!b) & (0 < c1));
c1 += (b & (i != 0));
}
return -c0;
}
int pi_max(uint8_t byte) { return -pi_min(~byte); }
// The obvious version for comparison.
int pi(uint8_t bit) { return bit ? 1 : -1; }
int pi_min_simple(uint8_t byte) {
int sum = 0;
int m = 9;
for (int i = 0; i < 8; ++i) {
uint8_t b = byte & (1 << (7-i));
sum += pi(b);
m = std::min(m, sum);
}
return m;
}
Sorry for the delay, I have measured the performance of the different methods now.
http://s12.postimg.org/v400xibxp/prefix_Sums.png
I am very glad to see that the solution suggested by Adam Burry is very efficient (the yellow line). As you can see, even the naive algorithm is slightly faster than the table lookup (green and brown lines) for both minimum and maximum prefix sum computation, which are indeed very similar... The most surprising thing (at least for me) is the terrible performance of maxExcess (which simply returned -pi_min(~byte), as Adam Burry suggested, where pi_min is the function representing the yellow line). I guess that it has to do with the additional overhead to compute the binary complement of each and every byte being analyzed, so I will switch to the original algorithm (pi_min) and return -c1 instead to implement pi_max.