How Can I Remove Pixel Noise from ofxKinect Video? - c++

I'm looking for some help figuring out how to remove some low quality pixel noise from a video, that I'm obtaining from an xbox kinect via open frameworks. I'm running logic against "moving" parts of an image, to determine what color is moving the most, and use those regions to also detect the depth of which those pixels are moving. I'm attaching a photo to try to better explain my issue.
http://imago.bryanmoyles.com/xxw80
Of course I know code will be asked for, so I'll post what I have so far, but what I'm looking for more than anything else, is a good algorithm for smoothing out pixelated regions in a photo using C++
for(int y = 0; y < kinect.height; y += grid_size) {
for(int x = 0; x < kinect.width * 3; x += 3 * grid_size) {
unsigned int total_r = 0, total_b = 0, total_g = 0;
for(int r = 0; r < grid_size; r++) {
for(int c = 0; c < grid_size; c++) {
total_r += color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 0)];
total_b += color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 1)];
total_g += color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 2)];
}
}
unsigned char average_r = total_r / (grid_size * grid_size),
average_b = total_b / (grid_size * grid_size),
average_g = total_g / (grid_size * grid_size);
for(int r = 0; r < grid_size; r++) {
for(int c = 0; c < grid_size; c++) {
color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 0)] = average_r;
color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 1)] = average_b;
color_pixels[(y * kinect.width * 3 + r * kinect.width * 3) + (c * 3 + x + 2)] = average_g;
}
}
}
}
for(int y = 0; y < kinect.height; y++) {
for (int x = 0; x < kinect.width * 3; x += 3) {
int total_difference = abs(color_pixels[y * kinect.width * 3 + x + 0] - rgb[0])
+ abs(color_pixels[y * kinect.width * 3 + x + 1] - rgb[1])
+ abs(color_pixels[y * kinect.width * 3 + x + 2] - rgb[2]);
unsigned char defined_color;
if(total_difference < 40) {
defined_color = (unsigned char) 255;
} else {
defined_color = (unsigned char) 0;
}
color_pixels[y * kinect.width * 3 + x + 0] = defined_color;
color_pixels[y * kinect.width * 3 + x + 1] = defined_color;
color_pixels[y * kinect.width * 3 + x + 2] = defined_color;
}
}
Again, I'd like to reiterate that my code is not the problem, I'm simply posting it here so that you understand I'm not just asking blindly. What I really need, is some direction on how to smooth out pixelated images, so that my averages don't get messed up frame by frame by poor quality.

You can process your image from the camera with some methods from the ofxOpenCV addon. There you will have methods like blur, undistort, erode, etc. Its easy to setup, because its already an addon. Have a look at the openCvExample which should be packed with your openFrameworks. For more information on the mentioned methods, take a look here. If I understand your problem correctly, then a little blur on the image could fix your problem already.

Related

Implementing the Lanczos algorithm into C++ for a quantum anharmonic oscillator

Firstly, I would like to mention that I am a complete beginner when it comes to coding, let alone C++, so bear with me, as I need complete guidance. My task is to implement the Lanczos algorithm for the case of a 1-D anharmonic oscillator in C++, with reference to the paper linked Analytical Lanczos method.
The paper offers a step by step guide for the implementation of the algorithm:
Step by step guide here
with the initial trial function being: Psi_1 = (1 + x^2) * (exp(-x^2 - 1/4 * x^4).
The paper also contains code in MATHEMATICA for this particular case. Mathematica code
and thus, here is my attempt, which is greatly unfinished, however, I wanted to ensure I was going along the correct path with regards to the programming logic. There are still plentiful errors etc. (Also excuse the lack of fundamentals here, I am only a beginner. Thank you very much.)
int main() {
//Grid parameters.
const int Rmin = 1, Rmax = 31, nx = 300;//Grid length and stepsize.
double dx = (Rmax- Rmin) / nx; //Delta x.
double a, b;
std::vector<double> x, psi_1;
for (int j = 1; j < 64; ++j) { //Corresponds to each succesive Lanczos Vector.
for (int i = Rmin; i < nx + 1; i++) { //Defining the Hamiltonian on the grid.
x[i] = (nx / 2) + i;
psi_1[i] = (1 + pow(x[i] * dx, 2)) * exp(pow(-x[i] * dx, 2) - (1 / 4 * pow(x[i] * dx, 4 )) //Trial wavefunction.
H[i] = ((PSI[j][i + 1] - 2 * PSI[j][i] + PSI[j][i - 1]) / pow(dx, 2)) + PSI[j][i] * 1/2 * pow(x[i] * dx, 2) + PSI[j][i] * 2 * pow(x[i] * dx, 4) + PSI[j][i] * 1/2 * pow(x[i], 6); //Hamiltonian. ****
//First Lanczos step.
PSI[1][i] = psi_1[i]
}
//Normalisation of the wavefunction (b).
double b[j] = 0.0;
for (int i = Rmin; i < nx + 1; i++) {
PSI[1][i] = psi_1[i];
b[j] += abs(pow(PSI[j][i], 2));
}
b[j] = b[j] * dx;
for (int i = Rmin; i < nx + 1; i++) {
PSI[j] = PSI[j] / sqrt(b[j]);
}
//Expectation values (a). Main diagonal of the Hamiltonian matrix.
double a[j] = 0.0;
for (int i = Rmin; i < nx + 1; i++) {
a[j] += PSI[j] * H[i] * PSI[j] * dx
}
//Recursive expression.
PSI[j] = H[i] * PSI[j-1] - PSI[j-1] * a[j-1] - PSI[j-2] * b[j-1]
//Lanczos Matrix.
LanczosMatrix[R][C] =
for (int R = 1; R < 64; R++) {
row[R] =
}
}
I have yet to finish the code, but some experienced guidance would be greatly appreciated! (also, the code has to be cleaned up greatly, but this was an attempt to get the general idea down first.)

How do I handle edge pixels from a image without any libraries but the standart ones from C++?

I have developed a code that can read and handle the bits from a 24 bits bmp image, mostly applying filters, but now I want to make my blur filter to blur the edge pixels too. Right now I have a 1 pixel edge, I'm using a 3x3 box blur, and this is the image I get after the blur is applied:
https://i.stack.imgur.com/0Px6Z.jpg
I'm able to keep the original bits from the image if I use an if statement in my inner loop but that doesn't really help given that I want it to be blurred and not the original unblurred bits.
Here is the code:
>
for (int count = 0; count < times; ++count) {
for (int x = 1; x < H-1; ++x) {
for (int y = 1; y < W-1; ++y) {
double sum1 = 0;
double sum2 = 0;
double sum3 = 0;
for (int k = -1; k <= 1; ++k) {
for (int j = -1; j <= 1; ++j) {
sum1 += bits[((x - j) * W + (y - k)) * 3] * kernel[j + 1][k + 1];
sum2 += bits[((x - j) * W + (y - k)) * 3 + 1] * kernel[j + 1][k + 1];
sum3 += bits[((x - j) * W + (y - k)) * 3 + 2] * kernel[j + 1][k + 1];
}
}
if (sum1 <= 0) sum1 = 0;
if (sum1 >= 255) sum1 = 255;
if (sum2 <= 0) sum2 = 0;
if (sum2 >= 255) sum2 = 255;
if (sum3 <= 0) sum3 = 0;
if (sum3 >= 255) sum3 = 255;
temp[(x * W + y) * 3] = sum1;
temp[(x * W + y) * 3 + 1] = sum2;
temp[(x * W + y) * 3 + 2] = sum3;
}
}
bits = temp;
}
I know that 5 for loops nested are really slow but I would like to be able to make it work properly first, but if there are any tips on how to improve it I'm all ears.
Now as for the first loop, what it does is it applies the filter the amount of times you want.
The next two is to go through the vector as a 2d vector, and the inner 2 are for the box blur.
Important things to know: I have a vector of bits(RGB) and not just the pixels, that is why I treat them one by one(bits), also my vector is a 1d vector.

sobel filter algorithm (C++) (no libraries)

I am trying to apply the sobel filter algorithm to a given picture (grayscale in this case) given my approach to accessing the pixels of the picture. Since I am accessing them in a way that doesn't use libraries, I am having trouble figuring out how to apply the algorithm given this approach. This first part of the code is just accessing pixel data:
Part 1:
CKingimageDoc* pDoc = GetDocument(); // get picture
int iBitPerPixel = pDoc->_bmp->bitsperpixel; // used to see if grayscale(8 bits) or RGB (24 bits)
int iWidth = pDoc->_bmp->width;
int iHeight = pDoc->_bmp->height;
BYTE *pImg = pDoc->_bmp->point; // pointer used to point at pixels in the image
const int area = iWidth * iHeight;
int Wp = iWidth;
int intensity;
if (iBitPerPixel == 8) ////Grayscale 8 bits image
{
int r = iWidth % 4; // pixels leftover from width (remainder has to be factor of 8 or 24)
int p = (4-r) % 4; // has to be a factor of number of bits in pixel, num leftover to take care of
Wp = iWidth + p;
Part 2 (The actual application of the sobel filter algorithm):
float kernelx[3][3] = { { -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 } };
float kernely[3][3] = { { -1, -2, -1 },
{ 0, 0, 0 },
{ 1, 2, 1 } };
double magX = 0.0; // this is your magnitude
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
magX += pImg[i*Wp + j] * kernelx[a][b]; // where i get confused
}
}
}
Any and all help is greatly appreciated.
You have to use appropriate pixel from neighborhood of center pixel to multiply with kernel entry:
//row, col - coordinates of central pixel for calculation
for (int row = 1; row < height - 1; row++) {
for (int col = 1; col < width - 1; col++) {
double magX = 0.0; // this is your magnitude
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
magX += pImg[(row - 1 + a) * Wp + col - 1 + b] * kernelx[a][b];
}
}
resultImg[row * Wp + col] = magX;
}
}
I omitted border pixels
CKingimageDoc* pDoc = GetDocument(); // get picture
int iBitPerPixel = pDoc->_bmp->bitsperpixel; // used to see if grayscale(8b) or RGB(24b)
int iWidth = pDoc->_bmp->width;
int iHeight = pDoc->_bmp->height;
BYTE *pImg = pDoc->_bmp->point; // pointer used to point at pixels in the image
const int area = iWidth * iHeight;
BYTE *pImg2 = new BYTE[area];
if (iBitPerPixel == 8) // Grayscale 8bit image
{
int pixel_x;
int pixel_y;
float sobel_x[3][3] =
{ { -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 } };
float sobel_y[3][3] =
{ { -1, -2, -1 },
{ 0, 0, 0 },
{ 1, 2, 1 } };
for (int x=1; x < iWidth-1; x++)
{
for (int y=1; y < iHeight-1; y++)
{
pixel_x = (sobel_x[0][0] * pImg[iWidth * (y-1) + (x-1)])
+ (sobel_x[0][1] * pImg[iWidth * (y-1) + x ])
+ (sobel_x[0][2] * pImg[iWidth * (y-1) + (x+1)])
+ (sobel_x[1][0] * pImg[iWidth * y + (x-1)])
+ (sobel_x[1][1] * pImg[iWidth * y + x ])
+ (sobel_x[1][2] * pImg[iWidth * y + (x+1)])
+ (sobel_x[2][0] * pImg[iWidth * (y+1) + (x-1)])
+ (sobel_x[2][1] * pImg[iWidth * (y+1) + x ])
+ (sobel_x[2][2] * pImg[iWidth * (y+1) + (x+1)]);
pixel_y = (sobel_y[0][0] * pImg[iWidth * (y-1) + (x-1)])
+ (sobel_y[0][1] * pImg[iWidth * (y-1) + x ])
+ (sobel_y[0][2] * pImg[iWidth * (y-1) + (x+1)])
+ (sobel_y[1][0] * pImg[iWidth * y + (x-1)])
+ (sobel_y[1][1] * pImg[iWidth * y + x ])
+ (sobel_y[1][2] * pImg[iWidth * y + (x+1)])
+ (sobel_y[2][0] * pImg[iWidth * (y+1) + (x-1)])
+ (sobel_y[2][1] * pImg[iWidth * (y+1) + x ])
+ (sobel_y[2][2] * pImg[iWidth * (y+1) + (x+1)]);
int val = (int)sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y));
if(val < 0) val = 0;
if(val > 255) val = 255;
pImg2[iHeight * y + x] = val;
}
}
}

C++/3D Terrain: std::vector pushback() crashes with c0000374

When attempted to push back a vector of UINT, the progrma crashes with Critical error detected c0000374. Below is the initial code:
void Terrain::CreateIndexList(UINT Width, UINT Height){
UINT sz_iList = (Width - 1)*(Height - 1) * 6;
UINT *iList = new UINT[sz_iList];
for (int i = 0; i < Width; i++){
for (int j = 0; j < Height; j++){
iList[(i + j * (Width - 1)) * 6] = ((UINT)(2 * i));
iList[(i + j * (Width - 1)) * 6 + 1] = (UINT)(2 * i + 1);
iList[(i + j * (Width - 1)) * 6 + 2] = (UINT)(2 * i + 2);
iList[(i + j * (Width - 1)) * 6 + 3] = (UINT)(2 * i + 2);
iList[(i + j * (Width - 1)) * 6 + 4] = (UINT)(2 * i + 1);
iList[(i + j * (Width - 1)) * 6 + 5] = (UINT)(2 * i + 3);
}
}
for (int i = 0; i < sz_iList; i++){
Geometry.IndexVertexData.push_back(iList[i]);
}
delete[] iList;
}
The goal is to take the generated indices from the iList array and fill the Geometry.IndexVertexData vector array. While debugging this, I've created several other implementations of this:
//After creating the iList array:
Geometry.IndexVertexData.resize(sz_iList); //Fails with "Vector subscript out of range?"
UINT in = 0;
for (int i = 0; i < Width; i++){
for (int j = 0; j < Height; j++){
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6] = iList[in];
in++;
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 1] = iList[in];
in++;
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 2] = iList[in];
in++;
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 3] = iList[in];
in++;
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 4] = iList[in];
in++;
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 5] = iList[in];
in++;
}
}
And a final, direct to vector implementation:
Geometry.IndexVertexData.reserve(sz_iList);
for (int index = 0; index < sz_iList; index+=6) {
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6] = ((UINT)(2 * i));
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 1] = (UINT)(2 * i + 1);
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 2] = (UINT)(2 * i + 2);
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 3] = (UINT)(2 * i + 2);
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 4] = (UINT)(2 * i + 1);
Geometry.IndexVertexData[(i + j*(Width - 1)) * 6 + 5] = (UINT)(2 * i + 3);
}
sz_iList has a final value of 2166, resultant from a grid of 20x20 (400 total points) and is used to initialize sizes. In all cases, the vector array would not fully fill, crashing with Critical error detected c0000374. Am I doing something wrong?
Your sz_iList doesn't appear to be big enough. Let's use a simple example of Width = Height = 2;, then sz_iList = (2 - 1) * (2 - 1) * 6 = 6, right? But in your nested loops, the last iteration occurs when i = j = 1 (i is one less than Width and j is one less than Height), where (in the last line of your loop), you try to access element (i + j * (Width - 1)) * 6 + 5 = (1 + 1 * (2 - 1)) * 6 + 5 = (1 + 1 * 1) * 6 + 5 = 2 * 6 + 5 = 17, which is bigger than the size of your array. This results in undefined behavior.

How come the bounding box isn't being set properly in this mesh?

I have some Irrlicht code that generates a rectangular mesh given a width and height. Here is the code that generates the vertices and indices:
int iNumVertices = (width + 1) * (height + 1);
S3DVertex * vertices = new S3DVertex[iNumVertices];
memset(vertices,0,sizeof(S3DVertex) * iNumVertices);
for(int i=0;i<=height;++i)
{
for(int j=0;j<=width;++j)
{
int iIndex = (i*(width + 1)) + j;
vertices[iIndex].Pos.X = i * 2.0f;
vertices[iIndex].Pos.Y = 0.0f;
vertices[iIndex].Pos.Z = j * 2.0f;
vertices[iIndex].Color.color = 0xFFFFFFFF;
vertices[iIndex].TCoords.X = i;
vertices[iIndex].TCoords.Y = j;
}
}
int iNumIndices = 6 * width * height;
u16 * indices = new u16[iNumIndices];
for(int i=0;i<height;++i)
{
for(int j=0;j<width;++j)
{
int iIndex = ((i*width) + j) * 6;
int tmp_offset = j + (i * (width + 1));
indices[iIndex + 0] = tmp_offset + 1;
indices[iIndex + 1] = tmp_offset + width + 1;
indices[iIndex + 2] = tmp_offset;
indices[iIndex + 3] = tmp_offset + 1;
indices[iIndex + 4] = tmp_offset + width + 2;
indices[iIndex + 5] = tmp_offset + width + 1;
}
}
Then the vertices and indices are added to the mesh and the bounding box is recalculated:
SMeshBuffer * buffer = new SMeshBuffer();
buffer->append(vertices,iNumVertices,indices,iNumIndices);
buffer->recalculateBoundingBox();
However, when rendered, the bounding box is nowhere close to the right size:
The end result of this is that the mesh doesn't get rendered when the small bounding box goes behind the camera.
Turns out that the problem was that I was calling recalculateBoundingBox() on the buffer instead of the mesh.