I'm doing some computing on raw video YUV file. The idea is to move a 8x8 window accross the entire frame, pixel by pixel. Here's my code:
while ( (frameNumber < maxFrame) &&
(fread_s(frame1, frameSize, 1, frameSize, file1)== frameSize) &&
(fread_s(frame2, frameSize, 1, frameSize, file2)) == frameSize)
{
unsigned char *p1 = frame1; //pointer to indicate start of a window
unsigned char *p2 = frame2;
unsigned char *p8_1 = NULL; //pointer used to navigate accross 8x8window
unsigned char *p8_2 = NULL;
for (int i = 0; i < countY; i += stepSize)
{
p1 += i*width; //move to next line
p2 += i*width;
for (int j = 0; j < countX; j += stepSize)
{
meanLuma1 = 0;
meanLuma2 = 0;
//8x8 window loop
for (int k = 0; k < windowSize; k++)
{
p8_1 = p1 + k*width; //move to next line of a window
p8_2 = p2 + k*width;
for (int l = 0; l < windowSize; l++)
{
meanLuma1 += *p8_1;
meanLuma2 += *p8_2; //Access violation here at i=60, others are 0
++p8_1;
++p8_2;
}
}
meanLuma1 = meanLuma1 / (windowSize*windowSize);
meanLuma2 = meanLuma2 / (windowSize*windowSize);
++p1;
++p2;
}
I keep getting access violation exception on p8_2 (i=60 ; j,k,l=0). I think it's weird, that p8_1 reads its value successfully but p8_2 does not, because both files have same size and dimensions. Variable states are following:
width=352;
height=288;
stepSize=4;
windowSize=8;
And I'm computing maximum number of steps like following:
int countX = ((width - windowSize) / stepSize)+1;
int countY = ((height - windowSize) / stepSize)+1;
Second strangeness is that if I set windowSize = 16 and stepSize = 8 , it compiles successfully.
Don't you see any obvious issues? I'm struggling with finding the bug for ages.
Seems here is an error in lines:
p1 += i*width; //move to next line
p2 += i*width;
You move on too far in arithmetical progression on each step. Try:
p1 += width; //move to next line
p2 += width;
or
p1 += stepSize*width; //move to next line
p2 += stepSize*width;
(depends on width and stepSize measure units).
Related
I recently asked question about how to work with element Edit1 dynamically, now I want to ask something about values, which I received from dynamical arrays. First I try to divide image into sectors:
const n=20;
unsigned short i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
unsigned short border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
Image1->Canvas->Pen->Color = clRed;
for (i = 0; i <= n; i++)
{
Image1->Canvas->MoveTo(0, 0);
line_length = w * tan(M_PI/2*i/n);
if (line_length <= h)
Image1->Canvas->LineTo(w, line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*i/n));
Image1->Canvas->LineTo(line_length, h);
}
}
Then I use regions to count black dots in each sector and I want to add values to element Memo:
HRGN region[n];
TPoint points[3];
points[0] = Point(l + border, t + topborder);
for (i = 0; i < n; i++)
{
for (j = 0; j <= 1; j++)
{
line_length = w * tan(M_PI/2*(i+j)/n);
if (line_length <= h)
points[j+1] = Point(l + border + w, t + topborder + line_length);
else
{
line_length = h * tan(M_PI/2*(1-1.*(i+j)/n));
points[j+1] = Point(l + border + line_length, t + topborder + h);
}
}
region[i] = CreatePolygonRgn(points, 3, ALTERNATE); // or WINDING ?? as u want
}
Byte k;
unsigned __int64 point_count[n] = {0}, points_count = 0;
for(j = 0; j < h; j++)
for (i = 0; i < w; i++)
if (Image1->Canvas->Pixels[i][j] == clBlack)
{
points_count++;
for (k = 0; k < n; k++)
if (PtInRegion(region[k], l + border + i, t + topborder + j))
point_count[k]++;
}
unsigned __int64 sum = 0;
for (i = 0; i < n; i++)
{
sum += point_count[i];
Memo1->Lines->Add(point_count[i]);
}
As i received an advice from one man, in order to allocate an array using a TEdit to specify the array's count I should use, for example DynamicArray:
#include <sysdyn.h>
DynamicArray<HRGN> region;
...
int n = Edit1-> Text.ToInt();
region.Length = n;
I have made the same changes to point_count array:
Byte k;
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
unsigned __int64 /*point_count[n] = {0},*/ points_count = 0;
...
The problem is that I received different values if I do it dynamically or statically(n=20).
Statically:
Dynamically:
The problem is that I received different values if I do it dynamically or statically(n=20)
There is no difference whatsoever in accessing elements of a static array vs a dynamic array. Your problem has to be elsewhere.
For instance, your static code is initializing all of the array elements to 0, but your dynamic code is not doing that, so they will have random values before your loop then increments them.
Try this:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
for(int i = 0; i < n; ++i) {
point_count[i] = 0;
}
...
Alternatively:
DynamicArray<unsigned __int64> point_count;
point_count.Length = n;
ZeroMemory(&point_count[0], sizeof(unsigned __int64) * n);
...
Also, using the Image1->Canvas->Pixels[][] property is very slow. Consider using the Image1->Picture->Bitmap->ScanLine[] property instead for faster access to the raw pixels.
I have the raw color data for four images, let's call them 1, 2, 3, and 4. I am storing the data in an unsigned char * with allocated memory. Individually I can manipulate or encode the images but when trying to concatenate or order them into a single image it works but takes more time than I would like.
I would like to create a 2 by 2 of the raw image data to encode as a single image.
1 2
3 4
For my example each image is 400 by 225 with RGBA (360000 bytes). Iim doing a for loop with memcpy where
for (int j = 0; j < 225; j++)
{
std::memcpy(dest + (j * (400 + 400) * 4), src + (j * 400 * 4), 400 * 4); //
}
for each image with an offset for the starting position added in (the example above would only work for the top left of course).
This works but I'm wondering if this is a solved problem with a better solution, either in an algorithm described somewhere or a small library.
#include <iostream>
const int width = 6;
const int height = 4;
constexpr int n = width * height;
int main()
{
unsigned char a[n], b[n], c[n], d[n];
unsigned char dst[n * 4];
int i = 0, j = 0;
/* init data */
for (; i < n; i++) {
a[i] = 'a';
b[i] = 'b';
c[i] = 'c';
d[i] = 'd';
}
/* re-order */
i = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++, i++, j++) {
dst[i ] = a[j];
dst[i + width] = b[j];
dst[i + n * 2 ] = c[j];
dst[i + n * 2 + width] = d[j];
}
i += width;
}
/* print result */
i = 0;
for (int y = 0; y < height * 2; y++) {
for (int x = 0; x < width * 2; x++, i++)
std::cout << dst[i];
std::cout << '\n';
}
return 0;
}
I am writing a code to find a cluster, I am using "cern root" to plot graphs,
the data is saved in ".root" file, but the code is written in c++. The data is saved as a 2D histogram. The logic of the code is once I find a bin with some signal in it, I find the neighbours around it (8 bins), then I tag the bin and increase the cluster size, and then do the same for the neighbour. I started by making a fiction to find the neighbour (the function returns an array with the x coordinate and another finds the y coordinate)
int* neighbour_function_i(int i){
int* neighbour_i = new int[8]; // Pointer to int, initialize to nothing.
neighbour_i[0] = {i-1}, neighbour_i[1] = {i}, neighbour_i[2] = {i+1}, neighbour_i[3] = {i-1}, neighbour_i[4] = {i+1}, neighbour_i[5] = {i-1}, neighbour_i[6] = {i}, neighbour_i[7] = {i+1};
return neighbour_i; //check if this works
}
the code that finds the cluster is as below
int* temp_neighbour_i = NULL;
int* temp_neightbour_j = NULL;
int uncheckedneighbours, total_neighbours;
int clsize = 0;
int temp_i,temp_j;
for(int i = 0; i < NPIXAX; i++){
for(int j = 0; j < NPIXAY; j++){
clsize = 0;
if(h->GetBinContent(i + 1, j + 1) - ped[i][j] > 0 && pedbf[i][j] == 0){//condition to find a cluster
pedbf[i][j] = 1; //Tag arry
clsize = 1;
uncheckedneighbours = 8;
total_neighbours = uncheckedneighbours;
int* neighbour_i = neighbour_function_i[i];//the error is here
int* neighbour_j = neighbour_function_j[j];//the error is here
while(uncheckedneighbours != 0){
for(int n = 0; n < total_neighbours; n++){
temp_i = neighbour_i[n];//Temp int for coordienate
temp_j = neighbour_j[n];//Temp int for coordinate
if(h->GetBinContent(temp_i, temp_j) - ped[temp_i][temp_j] > 0 && pedbf[temp_i][temp_j] == 0){//condition to find a cluster
pedbf[temp_i][temp_j] = 1;
int* new_neighbour_i = neighbour_function_i[temp_i];//the error is here
int* new_neighbour_j = neighbour_function_j[temp_j];//the error is here
uncheckedneighbours += 8;
total_neighbours += 8;
int* temp_neighbour_i = new int[clsize * 8];
int* temp_neighbour_j = new int[clsize * 8];
clsize++;
temp_neighbour_i[n] = neighbour_i[n];//moving data to chnage the size of neighbour/i array
temp_neighbour_j[n] = neighbour_j[n];//moving data to change the size of neighbour_j array
delete[] neighbour_i;//deallocate neighbour
delete[] neighbour_j;//deallocate neighbour
int *neighbour_i = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
int *neighbour_j = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
for(int x = 0; x < (clsize - 1) * 8; x++){ //neighbour = temp_neighbour + new_neighbour
neighbour_i[x] = temp_neighbour_i[x];
neighbour_j[x] = temp_neighbour_j[x];
}
for(int x = (clsize - 1)*8; x < clsize * 8; x++){
neighbour_i[x] = new_neighbour_i[x];
neighbour_j[x] = new_neighbour_j[x];
}
delete[]temp_neighbour_i; //dealocate temp and new
delete[]temp_neighbour_j; //dealocate temp and new
delete[]new_neighbour_i; //dealocate temp and new
delete[]new_neighbour_j; //dealocate temp and new
}
uncheckedneighbours--;
}
}
//if(clsize != 0){;//output to file cluseter size, i, j
//}
}
}
}
I am not sure why I am getting this error "subscript of pointer to function type 'int *(int)'"?
Maybe question should be closed as typo, but a function gets called like this:
int* neighbour_i = neighbour_function_i(i);
Not like this:
int* neighbour_i = neighbour_function_i[i];
I have this code that implements Prewitt edge detection. What I need to do is to implement it with only one buffer, meaning, I will not create copy of the image but edit original image. So if i want to change pixel with value 78, I cant put the new value e.g. 100 until all surrounding pixels have read value 78. Color values of the pixels. I have tried all day to figure it out but couldn't, if someone would write me some kind of pseudocode I would be very grateful
void filter_serial_prewitt(int *inBuffer, int *outBuffer, int width, int height){
for (int i = 1; i < width - 1; i ++) {
for (int j = 1; j < height - 1; j ++) {
int Fx = 0;
int Fy = 0;
int F = 0;
for (int m = -1; m <= 1; m++) {
for (int n = -1; n <= 1; n++) {
Fx += inBuffer[(j + n) * width + (i + m)] * n;
Fy += inBuffer[(j + n) * width + (i + m)] * m;
}
}
F = abs(Fx) + abs(Fy);
if (F < THRESHOLD){
outBuffer[j * width + i] = 255;
} else{
outBuffer[j * width + i] = 0;
}
}
}
}
One thing to know about a Prewitt operator is that it is separable. See the Wikipedia article for details.
To calculate a single output row, you need to do the following (pseudocode):
int* buffer = malloc (sizeof(int) * width);
for (int i = 0; i < width; i++)
{
// Do the vertical pass of the convolution of the first 3 rows into
// the buffer.
buffer [ i ] = vertical_convolve(inBuffer [ i ], vertical_kernel);
}
// Next, do the horizontal convolution of the first row. We need to
// keep the previous value in a temp buffer while we work
int temp0 = horizontal_convolve(buffer [ 0 ], horizontal_kernel);
for (int i = 1; i < width; i++)
{
int temp1 = horizontal_convolve(buffer[ i ], horizontal_kernel);
inBuffer [ i - 1 ] = temp0;
temp0 = temp1;
}
That requires a buffer that is 1 pixel tall and the width of the image.
To work on the whole image, you need to keep 2 of the above buffers around and after you calculate a pixel on the third line, you can replace the first pixel of the first line of the image with the first pixel of the first buffer. Then you can put the newly calculated value into the buffer.
So in this scenario, you won't keep around an entire second image, but will need to keep around 2 1-pixel tall buffers that are as wide as the image.
I have points in an image. I need to detect the most collinear points. The fastest method is to use Hough transform, but I have to modify the opencv method. Actually I need that the semi collinear points to be returned with detected line, for this reason I modified the polar line struct. A tolerance threshold is also needed to detect nearly detected points as shown in the image. Can someone help in how to tune this threshold?
I need at least four semi collinear points to detect the line to which they belong.
The points of first image were detected by 6 overlapped lines
the point of middle images were detected by nothing
the third's points
were detected by three lines
Which is the best way to get rid from the overlapped liens?? Or how to tune the tolerance threshold to detect the semi collinear points by only one line?
the is my own function call:
vector<CvLinePolar2> lines;
CvMat c_image = source1; // loaded image
HoughLinesStandard(&c_image,1,CV_PI/180,4,&lines,INT_MAX);
typedef struct CvLinePolar2
{
float rho;
float angle;
vector<CvPoint> points;
};
void HoughLinesStandard( const CvMat* img, float rho, float theta,
int threshold, vector<CvLinePolar2> *lines, int linesMax= INT_MAX )
{
cv::AutoBuffer<int> _accum, _sort_buf;
cv::AutoBuffer<float> _tabSin, _tabCos;
const uchar* image;
int step, width, height;
int numangle, numrho;
int total = 0;
int i, j;
float irho = 1 / rho;
double scale;
vector<vector<CvPoint>> lpoints;
CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 );
image = img->data.ptr;
step = img->step;
width = img->cols;
height = img->rows;
numangle = cvRound(CV_PI / theta);
numrho = cvRound(((width + height) * 2 + 1) / rho);
_accum.allocate((numangle+2) * (numrho+2));
_sort_buf.allocate(numangle * numrho);
_tabSin.allocate(numangle);
_tabCos.allocate(numangle);
int *accum = _accum, *sort_buf = _sort_buf;
float *tabSin = _tabSin, *tabCos = _tabCos;
memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) );
//memset( lpoints, 0, sizeof(lpoints) );
lpoints.resize(sizeof(accum[0]) * (numangle+2) * (numrho+2));
float ang = 0;
for(int n = 0; n < numangle; ang += theta, n++ )
{
tabSin[n] = (float)(sin(ang) * irho);
tabCos[n] = (float)(cos(ang) * irho);
}
// stage 1. fill accumulator
for( i = 0; i < height; i++ )
for( j = 0; j < width; j++ )
{
if( image[i * step + j] != 0 )
{
CvPoint pt;
pt.x = j; pt.y = i;
for(int n = 0; n < numangle; n++ )
{
int r = cvRound( j * tabCos[n] + i * tabSin[n] );
r += (numrho - 1) / 2;
int ind = (n+1) * (numrho+2) + r+1;
int s = accum[ind];
accum[ind]++;
lpoints[ind].push_back(pt);
}
}
}
// stage 2. find local maximums
for(int r = 0; r < numrho; r++ )
for(int n = 0; n < numangle; n++ )
{
int base = (n+1) * (numrho+2) + r+1;
if( accum[base] > threshold &&
accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
sort_buf[total++] = base;
}
// stage 3. sort the detected lines by accumulator value
icvHoughSortDescent32s( sort_buf, total, accum );
// stage 4. store the first min(total,linesMax) lines to the output buffer
linesMax = MIN(linesMax, total);
scale = 1./(numrho+2);
for( i = 0; i < linesMax; i++ )
{
CvLinePolar2 line;
int idx = sort_buf[i];
int n = cvFloor(idx*scale) - 1;
int r = idx - (n+1)*(numrho+2) - 1;
line.rho = (r - (numrho - 1)*0.5f) * rho;
line.angle = n * theta;
line.points = lpoints[idx];
lines->push_back(line);
}
}
One approach is non-maximal suppression to thin out the candidate set for potential lines. Once you've identified the thinned potential lines you could then compute an average of the remaining lines that would satisfy some angular or spatial difference threshold.
Try HoughLinesP..opencv reference