M
MyCatAlex
Guest
OK, this is the scoop. I have this crazy project that is based on MFCaptureD3D from github. The original project deals with output from a webcam and puts it on a screen. It is a high quality picture. I found a place in device.cpp to intercept the pixel values and my goal is to process these pictures electronically, independently of what MFCaptureD3D is doing. The webcam picture has width 320 pixels and hight - 240 pixels, therefore the total number of pixels is 76,800. The logic of the project demands that those pixels should be divided in small squares each containing about 88 pixels, theremofer the number of such squares whould be 894.
The problem I have is that taking the pixel values and storing them is a very fast process and my part that should process them is very slow, perhaps a couple of orders of magnitudes slower, q don't really know for sure. In order to try to manage the pixel values coming over at such a speed, I decided to use 3 storage area and the code should fill them sequentually. I hoped that my code will handle such a delay. This is the code to collect the pixel values. pcom is a structure. To fill one array like pcom.S0 for instance it takes less than 7 milliseconds.
counter += 1;
switch (pcom.rFlag) {
case 0:
pcom.s00[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 1;
counter = -1;
}
break;
case 1:
pcom.s01[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 2;
counter = -1;
break;
}
break;
case 2:
pcom.s02[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 0;
counter = -1;
break;
}
break;
}
Then there is this structure:
struct OutMemStream2 {
struct A1 {
struct W1 {
struct C1 {
float x1 = 0.0;
float y1 = 0.0;
} c[5];
} w[10];
} a[90];
int numb_a90 = -1;
float invariant = 0;
} b[864]; // Expected number of spherical rectangles total
The structure is so complicated because the values x1,y1 are in fact functions of a namber of variables, some of which are digital indices. The part of the code that I want to post now is supposed to read raw pixel amplitudes from arrays pcom.S00, pcom.S01, pcom.S02 sequentially, process them and store the results x1,y1 in the structure above.
for (int ii = 0; ii < pcom.H; ii++) // pcom.H == 240
{
for (int jj = 0; jj < pcom.W; jj++) // pcom.W == 320
{
pixelCounter += 1;
if (pixelCounter == 0)
{
start = std::chrono::system_clock::now();
}
DefineVars(diag, ii, jj, theta, phi);
// determine one of 864 spherical rectangles where the pixel in question belongs to
rectParalCoo = phi / 0.0872665; // 0.0872665 == 5 degrees in radians
colNum = std::floor(rectParalCoo);
rectMeridCoo = theta / 0.0872665;
rowNum = std::floor(rectMeridCoo);
int bNumber = rowNum * 72 + colNum; // bNumber is the sequential number of the spherical rect.
b[bNumber].numb_a90 += 1;
std::cout << " " << bNumber << " " << b[bNumber].numb_a90 << " " << pcom.rFlag << endl;
// just determined theta & phi angles for individual pixels
// find Spherical Harmonic for the pixels and to pull pixel's amplitude
switch (pcom.rFlag){
case 0:
value = pcom.s01[pixelCounter]; <== VERY FAST
break;
case 1:
value = pcom.s02[pixelCounter];
break;
case 2:
value = pcom.s00[pixelCounter];
break;
}
llCou = -1;
for (int ll = pcom.llMin; ll < pcom.llMax; ll++) // 10 values of ll
{
llCou += 1;
mmCou = -1; // VERY SLOW PART
for (int mm = pcom.mmMin; mm <= pcom.mmMax; mm++) // 5 values of mm
{
mmCou += 1;
res = (double)LegendrePolynomials::normSelector(cos(theta), ll, mm);
res *= pcom.factorArr[(int)diag]; // peripheral attenuation/modulation
res *= (float)value; // int value is the amplitude of signal at a pixel
// selection of the pixel input point by point
BytesWritten += sizeof(float);
b[bNumber].a[b[bNumber].numb_a90].w[llCou].c[mmCou].x1 = res * cos(phi * (float)mm);
b[bNumber].a[b[bNumber].numb_a90].w[llCou].c[mmCou].y1 = res * sin(phi * (float)mm);
// pfRArray [pixelCounter] = res * cos(phi * (float)mm); // real part
// pfIArray [pixelCounter] = res * sin(phi * (float)mm); // imaginary part
}
}
}
}
It is a simple piece of code, however it does not work because of the difference in speed. I run into exceptions and the pixels end up all being messed up. I know where the solution lies. I need to use either a mutex or a semaphore, but I don't know how to attach them to my code. I would appreciate if somebody will offer a helping hand.
Thank you - MyCatAlex
Continue reading...
The problem I have is that taking the pixel values and storing them is a very fast process and my part that should process them is very slow, perhaps a couple of orders of magnitudes slower, q don't really know for sure. In order to try to manage the pixel values coming over at such a speed, I decided to use 3 storage area and the code should fill them sequentually. I hoped that my code will handle such a delay. This is the code to collect the pixel values. pcom is a structure. To fill one array like pcom.S0 for instance it takes less than 7 milliseconds.
counter += 1;
switch (pcom.rFlag) {
case 0:
pcom.s00[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 1;
counter = -1;
}
break;
case 1:
pcom.s01[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 2;
counter = -1;
break;
}
break;
case 2:
pcom.s02[counter] = y0;
if (counter == 76799)
{
pcom.rFlag = 0;
counter = -1;
break;
}
break;
}
Then there is this structure:
struct OutMemStream2 {
struct A1 {
struct W1 {
struct C1 {
float x1 = 0.0;
float y1 = 0.0;
} c[5];
} w[10];
} a[90];
int numb_a90 = -1;
float invariant = 0;
} b[864]; // Expected number of spherical rectangles total
The structure is so complicated because the values x1,y1 are in fact functions of a namber of variables, some of which are digital indices. The part of the code that I want to post now is supposed to read raw pixel amplitudes from arrays pcom.S00, pcom.S01, pcom.S02 sequentially, process them and store the results x1,y1 in the structure above.
for (int ii = 0; ii < pcom.H; ii++) // pcom.H == 240
{
for (int jj = 0; jj < pcom.W; jj++) // pcom.W == 320
{
pixelCounter += 1;
if (pixelCounter == 0)
{
start = std::chrono::system_clock::now();
}
DefineVars(diag, ii, jj, theta, phi);
// determine one of 864 spherical rectangles where the pixel in question belongs to
rectParalCoo = phi / 0.0872665; // 0.0872665 == 5 degrees in radians
colNum = std::floor(rectParalCoo);
rectMeridCoo = theta / 0.0872665;
rowNum = std::floor(rectMeridCoo);
int bNumber = rowNum * 72 + colNum; // bNumber is the sequential number of the spherical rect.
b[bNumber].numb_a90 += 1;
std::cout << " " << bNumber << " " << b[bNumber].numb_a90 << " " << pcom.rFlag << endl;
// just determined theta & phi angles for individual pixels
// find Spherical Harmonic for the pixels and to pull pixel's amplitude
switch (pcom.rFlag){
case 0:
value = pcom.s01[pixelCounter]; <== VERY FAST
break;
case 1:
value = pcom.s02[pixelCounter];
break;
case 2:
value = pcom.s00[pixelCounter];
break;
}
llCou = -1;
for (int ll = pcom.llMin; ll < pcom.llMax; ll++) // 10 values of ll
{
llCou += 1;
mmCou = -1; // VERY SLOW PART
for (int mm = pcom.mmMin; mm <= pcom.mmMax; mm++) // 5 values of mm
{
mmCou += 1;
res = (double)LegendrePolynomials::normSelector(cos(theta), ll, mm);
res *= pcom.factorArr[(int)diag]; // peripheral attenuation/modulation
res *= (float)value; // int value is the amplitude of signal at a pixel
// selection of the pixel input point by point
BytesWritten += sizeof(float);
b[bNumber].a[b[bNumber].numb_a90].w[llCou].c[mmCou].x1 = res * cos(phi * (float)mm);
b[bNumber].a[b[bNumber].numb_a90].w[llCou].c[mmCou].y1 = res * sin(phi * (float)mm);
// pfRArray [pixelCounter] = res * cos(phi * (float)mm); // real part
// pfIArray [pixelCounter] = res * sin(phi * (float)mm); // imaginary part
}
}
}
}
It is a simple piece of code, however it does not work because of the difference in speed. I run into exceptions and the pixels end up all being messed up. I know where the solution lies. I need to use either a mutex or a semaphore, but I don't know how to attach them to my code. I would appreciate if somebody will offer a helping hand.
Thank you - MyCatAlex
Continue reading...