I am attempting to create a Worley Noise function. I looked around and read the original paper by Steven Worley and wrote my implementation. The output does not appear to be correct though. I expect to see something like this.
But it outputs this.
I'm not sure what I am doing wrong. I have looked online at other peoples programs and I do it the same way. Here is the code.
float WorleyNoise::noise( Vector3 input ) {
unsigned int lastRandom;
unsigned int numberFeaturePoints;
Vector3 randomDiff;
Vector3 featurePoint;
int cubeX;
int cubeY;
int cubeZ;
float distanceArray[ 3 ];
for ( int i = 0; i < 3; i++ ) {
distanceArray[ i ] = 6666.0f;
}
int evalX = ( int ) floorf( input.m_x );
int evalY = ( int ) floorf( input.m_y );
int evalZ = ( int ) floorf( input.m_z );
for ( int i = -1; i < 2; ++i ) {
for ( int j = -1; j < 2; ++j ) {
for ( int k = -1; k < 2; ++k ) {
cubeX = evalX + i;
cubeY = evalY + j;
cubeZ = evalZ + k;
lastRandom = lcg_random( hash( ( unsigned int ) ( cubeX + m_seed ), ( unsigned int ) cubeY, ( unsigned int ) cubeZ ) );
numberFeaturePoints = lookup( lastRandom );
for ( unsigned int l = 0; l < numberFeaturePoints; ++l ) {
lastRandom = lcg_random( lastRandom );
randomDiff.m_x = ( float ) lastRandom / 0x100000000;
lastRandom = lcg_random( lastRandom );
randomDiff.m_y = ( float ) lastRandom / 0x100000000;
lastRandom = lcg_random( lastRandom );
randomDiff.m_z = ( float ) lastRandom / 0x100000000;
featurePoint.m_x = randomDiff.m_x + ( float ) cubeX;
featurePoint.m_y = randomDiff.m_y + ( float ) cubeY;
featurePoint.m_z = randomDiff.m_z + ( float ) cubeZ;
insert( distanceArray, euclidian_distance( input, featurePoint ) );
}
}
}
}
return Utility::clampf( combine_function_1( distanceArray ), 0.0f, 1.0f );
}
unsigned int WorleyNoise::hash( unsigned int i, unsigned int j, unsigned int k ) {
return ( unsigned int ) ( ( ( ( ( ( OFFSET_BASIS ^ ( unsigned int ) i ) * FNV_PRIME ) ^ ( unsigned int ) j ) * FNV_PRIME ) ^ ( unsigned int ) k ) * FNV_PRIME );
}
unsigned int WorleyNoise::lcg_random( unsigned int last ) {
return ( unsigned int ) ( ( 1103515245 * last + 12345 ) % 0x100000000 );
}
void WorleyNoise::insert( float arr[] , float value ) {
float temp = 0.0f;
for ( int i = 2; i >= 0; i-- ) {
if ( value > arr[ i ] ) {
break;
}
temp = arr[ i ];
arr[ i ] = value;
if ( i + 1 < 3 ) {
arr[ i + 1 ] = temp;
}
}
}
unsigned int WorleyNoise::lookup( unsigned int value ) {
value = value & 0xffffffff;
if ( value < 393325350 )
return 1;
if ( value < 1022645910 )
return 2;
if ( value < 1861739990 )
return 3;
if ( value < 2700834071 )
return 4;
if ( value < 3372109335 )
return 5;
if ( value < 3819626178 )
return 6;
if ( value < 4075350088 )
return 7;
if ( value < 4203212043 )
return 8;
return 9;
}
float WorleyNoise::euclidian_distance( Vector3 p1, Vector3 p2 ) {
return ( p1.m_x - p2.m_x ) * ( p1.m_x - p2.m_x ) + ( p1.m_y - p2.m_y ) * ( p1.m_y - p2.m_y ) + ( p1.m_z - p2.m_z ) * ( p1.m_z - p2.m_z );
}
float WorleyNoise::combine_function_1( float arr[] ) {
return arr[ 0 ];
}
I then output the results like so with pngwriter.
void WorleyNoise::to_png( const std::string &file, unsigned int width, unsigned int height ) {
pngwriter png( width, height, 0, file.c_str() );
for ( unsigned int i = 0; i < width; i++ ) {
for ( unsigned int j = 0; j < height; j++ ) {
float value = noise( Vector3( i, j, 0 ) );
png.plot( i, j, ( double ) value, ( double ) value, ( double ) value );
}
}
png.close();
}
So what is going wrong here? I've looked all over, especially at this tutorial and cannot figure out why it does not output correctly. Any help is greatly appreciated, thanks.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to check how much time passes with each 3 solutions for a problem, but sometimes I get a runtime error and can't see the passed time for 3rd solution, but sometimes it works. I think the solutions.h file is correct but i put it here anyway.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "solutions.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
int* output1= new int[1000];
double duration;
clock_t startTime1 = clock();
solution1(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 1 with 10000 inputs took " << duration << " milliseconds." << endl;
startTime1 = clock();
solution2(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 2 with 10000 inputs took " << duration<< " milliseconds." << endl;
startTime1 = clock();
solution3(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 3 with 10000 inputs took " << duration << " milliseconds." << endl<<endl<<endl;
return 0;
}
And the solutions.h is
#ifndef SOLUTIONS_H_INCLUDED
#define SOLUTIONS_H_INCLUDED
#include <cmath>
void solution1( int input[], const int n, const int k, int output[] );
void solution2( int input[], const int n, const int k, int output[] );
void solution3( int input[], const int n, const int k, int output[] );
void swap( int &n1, int &n2 ) {
int temp = n1;
n1 = n2;
n2 = temp;
}
void solution1( int input[], const int n, const int k, int output[] ) {
int maxIndex, maxValue;
for( int i = 0; i < k; i++ ) {
maxIndex = i;
maxValue = input[i];
for( int j = i+1; j < n; j++ ) {
if( input[j] >= maxValue ) {
maxIndex = j;
maxValue = input[ j ];
}
}
swap( input[i], input[maxIndex] );
output[i] = input[i];
}
}
int partition( int input[], int p, int r ) {
int x = input[ r ], i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[i+1], input[r] );
return i + 1;
}
void quickSort( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition( input, p, r );
quickSort( input, p, q - 1 );
quickSort( input, q + 1, r );
}
}
void solution2( int input[], const int n, const int k, int output[] ) {
quickSort( input, 0, n - 1 );
for( int i = 0; i < k; i++ ) {
output[i] = input[i];
}
}
int partition2( int input[], int a, int p, int r ) {
int x = a, i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] == x ) {
swap( input[ j ], input[ r ] );
}
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[ i + 1 ], input[ r ] );
return i + 1;
}
void quickSort2( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition2( input, input[ r ], p, r );
quickSort2( input, p, q - 1 );
quickSort2( input, q + 1, r );
}
}
int findMin( int n1, int n2 ) {
if( n1 <= n2 )
return n1;
else
return n2;
}
int select( int input[], int n, int k, int start, int end, int flag ) {
if( n <= 5 ) {
quickSort2( input, start, end );
return input[ start + k - 1 ];
}
int i = start, numGroups = (int) ceil( ( double ) n / 5 ), numElements, j = 0;
int *medians = new int[numGroups];
while( i <= end ) {
numElements = findMin( 5, end - i + 1 );
medians[( i - start ) / 5] = select( input, numElements, (int) ceil( ( double ) numElements / 2 ), i, i + numElements - 1, 1 );
i = i + 5;
}
int M = select( medians, numGroups, (int) ceil( ( double ) numGroups / 2 ), 0, numGroups - 1, 1 );
delete[] medians;
if( flag == 1 )
return M;
int q = partition2( input, M, start, end );
int m = q - start + 1;
if( k == m )
return M;
else if( k < m )
return select( input, m - 1, k, start, q - 1, 0 );
else
return select( input, end - q, k - m, q + 1, end, 0 );
}
void solution3( int input[], const int n, const int k, int output[] ) {
select( input, n, k, 0, n - 1, 0 );
for( int i = 0; i < k; i++ )
output[i] = input[i];
}
#endif // SOLUTIONS_H_INCLUDED
Building your program with address sanitizer (clang++ clock.cxx -std=c++11 -O1 -g -fsanitize=address -fno-omit-frame-pointer) reveals the problem:
$ ./a.out
Hello world!
=================================================================
==8175==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62e00000a040 at pc 0x000104dbd912 bp 0x7fff5ae43970 sp 0x7fff5ae43968
WRITE of size 4 at 0x62e00000a040 thread T0
#0 0x104dbd911 in main clock.cxx:18
#1 0x7fff88cd85fc in start (libdyld.dylib+0x35fc)
#2 0x0 (<unknown module>)
0x62e00000a040 is located 0 bytes to the right of 40000-byte region [0x62e000000400,0x62e00000a040)
And there is your code:
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
As you can see, size of input1, input2, ..., input4 is 10K, 20K, 40K, 80K elements, but in the loop we are accessing to elements out of this array so this can lead to the heap corruption.
Process returned -1073741819 (0xC0000005)
This means "memory access violation" or SEGFAULT.
Hope this will help.
I have a large array (image) and I need to do many small configurable computations on that data.
I'll post an example here.
NOTE: This is not the actual problem, but a minimal / hopefully illustrative example of what I need to do.
// different functions that can be called based on the configuration
float func1( float* a )
{
return (*a) * (*a);
}
float func2( float* a )
{
return (*a) + (*a);
}
float func3( float* a )
{
return 2 * (*a) * (*a);
}
// my data
float* data = new float[1024*1024];
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
for ( int k = 0; k < 1024*1024; k++ )
{
if ( param1 == 2 && param2 == 0 )
data[k] = func1( data + k );
else if ( param1 == 1 && param2 == 1 )
data[k] = func2( data + k );
else if ( param1 == 0 && param2 == 1 )
data[k] = func3( data + k );
else
continue;
}
}
In my code, it does not make sense to put the loop inside of each function.
However, param1 and param2 remain constant during the loop and they are known at compile time.
Is there a way to remove the influence of the if/elseif statements?
You can move your if-else statement that selects appropriate function to use out of the loop, thus getting to:
#include <functional>
// different functions that can be called based on the configuration
float func1( float* a )
{
return (*a) * (*a);
}
float func2( float* a )
{
return (*a) + (*a);
}
float func3( float* a )
{
return 2 * (*a) * (*a);
}
// my data
float* data = new float[1024*1024];
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
std::function< float( float* )> functionToUse = nullptr;
if ( param1 == 2 && param2 == 0 )
functionToUse = std::function<float(float*)>(func1);
else if ( param1 == 1 && param2 == 1 )
functionToUse = std::function<float(float*)>(func2);
else if ( param1 == 0 && param2 == 1 )
functionToUse = std::function<float(float*)>(func3);
if(functionToUse){
for ( int k = 0; k < 1024*1024; k++ )
{
data[k] = functionToUse( data + k );
}
}
}
As to choosing the function to use during compilation time I'd suggest checking out this question:
if/else at compile time?
Also this question might be of interest:
Is cutting if statements by using function pointers going to be more efficient?
As long as the parameters are const OR the compiler can 100% determine that they variables aren't aliased and thus won't change (harder for the compiler) I would completely expect the optimizer to totally remove the runtime branch and do all the work at compile time.
If however you don't prefer to rely on the optimizer you can use templates:
template <int c1, int c2>
float func(float* a)
{
// No-op.
}
template <>
float func<2, 0>(float* a)
{
return (*a) * (*a);
}
template <>
float func<1, 1>(float* a)
{
return (*a) + (*a);
}
template <>
float func<0, 1>(float* a)
{
return 2 * (*a) * (*a);
}
int main()
{
const int param1 = 0;
const int param2 = 1;
for ( int k = 0; k < 1024*1024; k++ )
{
func<param1, param2>(<float ptr>);
}
}
Maybe something like this
#include <iostream>
#include <map>
#include <functional>
#include <utility>
typedef std::pair<size_t, size_t> pair;
typedef std::map< pair, std::function<float( float* )>> map;
// different functions that can be called based on the configuration
float func1( float* a )
{
return ( *a ) * ( *a );
}
float func2( float* a )
{
return ( *a ) + ( *a );
}
float func3( float* a )
{
return 2 * ( *a ) * ( *a );
}
// my data
float* data = new float[1024 * 1024];
void init( map &myMap )
{
myMap.insert( pair, std::function<float( float* )>>
( pair( 2, 0 ), std::function< float( float* )>( func1 ) ) );
myMap.insert( pair, std::function<float( float* )>>
( pair( 1, 1 ), std::function< float( float* )>( func2 ) ) );
myMap.insert( pair, std::function<float( float* )>>
( pair( 0, 2 ), std::function< float( float* )>( func3 ) ) );
}
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
map myMap;
init( myMap );
for( int k = 0; k < 1024 * 1024; k++ )
{
data[k] = myMap[pair( param1, param2 )]( data + k );
}
}
Iam trying to write a code in c++ to calculate PSNR of two yuv video files however everything should work but i get a segmentation fault error ..
any help here is highly appreciated
here is my code
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "base.h"
void makeAFrame( YuvFrame* f, int width, int height )
{
f->lum.width = width; f->lum.height = height;
f->cb .width = width/2; f->cb .height = height/2;
f->cr .width = width/2; f->cr .height = height/2;
}
void readColorComponent( ColorComponent* cc, FILE* file )
{
unsigned int size = cc->width*cc->height;
unsigned int rsize;
rsize = fread( cc->data, sizeof(unsigned char), size, file );
}
double psnr( ColorComponent& rec, ColorComponent& org)
{
unsigned char* pOrg = org.data;
unsigned char* pRec = rec.data;
double ssd = 0;
int diff;
for ( int r = 0; r < rec.height; r++ )
{
for( int c = 0; c < rec.width; c++ )
{
diff = pRec[c] - pOrg[c];
ssd += (double)( diff * diff );
}
pRec += rec.width;
pOrg += org.width;
}
if( ssd == 0.0 )
{
return 99.99;
}
return ( 10.0 * log10( (double)rec.width * (double)rec.height * 65025.0 / ssd ) );
}
void getPSNR( double& psnrY, double& psnrU, double& psnrV, YuvFrame& rcFrameOrg, YuvFrame& rcFrameRec )
{
psnrY = psnr( rcFrameRec.lum, rcFrameOrg.lum );
psnrU = psnr( rcFrameRec.cb, rcFrameOrg.cb );
psnrV = psnr( rcFrameRec.cr, rcFrameOrg.cr );
}
void readFrame( YuvFrame* f, FILE* file )
{
readColorComponent( &f->lum, file );
readColorComponent( &f->cb, file );
readColorComponent( &f->cr, file );
}
int main(int argc, char *argv[])
{
int acc = 10000;
#define OUT "%d,%04d"
int stream = 0;
unsigned int width = 0;
unsigned int height = 0;
unsigned int temporal_stages = 0;
unsigned int skip_at_start = 0;
double fps = 0.0;
FILE* org_file = 0;
FILE* rec_file = 0;
FILE* str_file = 0;
char* prefix_string = 0;
unsigned int index, skip, skip_between, sequence_length;
int py, pu, pv, br;
double bitrate = 0.0;
double psnrY, psnrU, psnrV;
YuvFrame cOrgFrame, cRecFrame;
double AveragePSNR_Y = 0.0;
double AveragePSNR_U = 0.0;
double AveragePSNR_V = 0.0;
int currarg = 5;
int rpsnr = 0;
width = 300;
height = 240;
org_file = fopen("foreman_qcif.yuv","rb");
rec_file = fopen("foreman_qcif2.yuv","rb");
temporal_stages=2;
fseek( rec_file, 0, SEEK_END );
fseek( org_file, 0, SEEK_END );
size_t rsize = ftell( rec_file );
size_t osize = ftell( org_file );
fseek( rec_file, 0, SEEK_SET );
fseek( org_file, 0, SEEK_SET );
if (rsize < osize)
{
sequence_length = (unsigned int)((double)rsize/(double)((width*height*3)/2));
}
else
{
sequence_length = (unsigned int)((double)osize/(double)((width*height*3)/2));
skip_between = ( 1 << temporal_stages ) - 1;
}
//here we try to make frames out of images
makeAFrame( &cOrgFrame, width, height );
makeAFrame( &cRecFrame, width, height );
//looping over all frames
for( skip = skip_at_start, index = 0; index < sequence_length; index++, skip = skip_between )
{
fseek( org_file, skip*width*height*3/2, SEEK_CUR);
readFrame ( &cOrgFrame, org_file );
readFrame ( &cRecFrame, rec_file );
getPSNR ( psnrY, psnrU, psnrV, cOrgFrame, cRecFrame);
AveragePSNR_Y += psnrY;
AveragePSNR_U += psnrU;
AveragePSNR_V += psnrV;
py = (int)floor( acc * psnrY + 0.5 );
pu = (int)floor( acc * psnrU + 0.5 );
pv = (int)floor( acc * psnrV + 0.5 );
fprintf(stdout,"%d\t"OUT"\t"OUT"\t"OUT"\n",index,py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
}
fprintf(stdout,"\n");
py = (int)floor( acc * AveragePSNR_Y / (double)sequence_length + 0.5 );
pu = (int)floor( acc * AveragePSNR_U / (double)sequence_length + 0.5 );
pv = (int)floor( acc * AveragePSNR_V / (double)sequence_length + 0.5 );
br = (int)floor( acc * bitrate + 0.5 );
if( stream )
{
if( prefix_string )
{
fprintf(stderr,"%s\t"OUT"\t"OUT"\t"OUT"\t"OUT"\n",prefix_string,br/acc,br%acc,py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
fprintf(stdout,"%s\t"OUT"\t"OUT"\t"OUT"\t"OUT"\n",prefix_string,br/acc,br%acc,py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
}
else
{
fprintf(stderr,OUT"\t"OUT"\t"OUT"\t"OUT"\n",br/acc,br%acc,py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
fprintf(stdout,OUT"\t"OUT"\t"OUT"\t"OUT"\n",br/acc,br%acc,py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
}
}
else
{
fprintf(stderr,"total\t"OUT"\t"OUT"\t"OUT"\n",py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
fprintf(stdout,"total\t"OUT"\t"OUT"\t"OUT"\n",py/acc,py%acc,pu/acc,pu%acc,pv/acc,pv%acc);
}
fprintf(stdout, "\n");
fclose ( org_file );
fclose ( rec_file );
if( stream )
{
fclose ( str_file );
}
return (rpsnr*py);
}
and base.h contains structures
typedef struct
{
int width;
int height;
unsigned char* data;
} ColorComponent;
typedef struct
{
ColorComponent lum;
ColorComponent cb;
ColorComponent cr;
} YuvFrame;
well, segmentation error arises from you trying to access memory addresses not assigned to you ... as w hot-fix to avoid the error add this function to your code
void foo( ColorComponent* cc )
{
if( ! ( cc->data = new unsigned char[cc->width * cc->height]))
{
fprintf(stderr, "\nERROR: memory allocation failed!\n\n");
exit(-1);
}
}
and change these lines
void makeAFrame( YuvFrame* f, int width, int height )
{
f->lum.width = width; f->lum.height = height;
f->cb .width = width/2; f->cb .height = height/2;
f->cr .width = width/2; f->cr .height = height/2;
}
to
void makeAFrame( YuvFrame* f, int width, int height )
{
f->lum.width = width; f->lum.height = height;
foo( &f->lum );
f->cb .width = width/2; f->cb .height = height/2;
foo( &f->cb );
f->cr .width = width/2; f->cr .height = height/2;
foo( &f->cr );
}
things should work now
I need to use calcBackProject and then display the exact number.
for ( int i = 0; i < backProj.rows; ++i )
{
for ( int j = 0; j < backProj.cols; ++j )
{
cout << int(backProj.at< uchar >( i, j )) << " ";
}
cout << endl;
}
But its max value is 255 because of "uchar".
I tried to use
Mat backProj( slid_.rows, slid_.cols, CV_64FC1 );
After using calcBackProject, display it
cout << backProj.at< double >( i, j );
but it does not work.
I really need the exact numbers which are bigger than 255. I don't want to use normalize before. Can I make it by calcBackProject?
If I try to scale it down, can this Back Projection matrix includes decimal? Because I don't want that 0 exists in this matrix.
Thank you.
Finally, I wrote my own function to get Back Projection. Hope it can help you who have same problem.
float ReadValueFromHist( const Mat& hist, const int x, const int y ) const
{
int indexAlpha = int( mat.at< Vec4b >( x, y )[ 3 ] ) * bins / 256;
return hist.at< float >( indexAlpha, 0 );
}
void CalcBackProj()
{
backProj = Mat( mat.rows, mat.cols, CV_32FC1);
for ( int i = 0; i < mat.rows; ++i )
{
for ( int j = 0; j < mat.cols; ++j )
{
backProj.at< float >( i, j ) = ReadValueFromHist( hist, i, j );
}
}
}
I'm new at computer vision, but i need to made a little function in C++, who will detect a white paper sheet even if is something printed on him, and the retrieve the 4 edges coordinates what is what i really need so i can use those coordinates and cut another jpg file and use the cutted image as a opengl textures.
I dont know how to detect the paper.
Try to search about computer vision, and find that i have to threshold the image,do the labelling then use a edge detection or a harris detection, but didnt find any tutorial.
Can any one help me with this, or show me some tutorial who can help me?
Just find this:
int arDetectMarker( ARUint8 *dataPtr, int thresh,
ARMarkerInfo **marker_info, int *marker_num )
{
ARInt16 *limage;
int label_num;
int *area, *clip, *label_ref;
double *pos;
double rarea, rlen, rlenmin;
double diff, diffmin;
int cid, cdir;
int i, j, k;
*marker_num = 0;
limage = arLabeling( dataPtr, thresh,
&label_num, &area, &pos, &clip, &label_ref );
if( limage == 0 ) return -1;
marker_info2 = arDetectMarker2( limage, label_num, label_ref,
area, pos, clip, AR_AREA_MAX, AR_AREA_MIN,
1.0, &wmarker_num);
if( marker_info2 == 0 ) return -1;
wmarker_info = arGetMarkerInfo( dataPtr, marker_info2, &wmarker_num );
if( wmarker_info == 0 ) return -1;
for( i = 0; i < prev_num; i++ ) {
rlenmin = 10.0;
cid = -1;
for( j = 0; j < wmarker_num; j++ ) {
rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area;
if( rarea < 0.7 || rarea > 1.43 ) continue;
rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0])
* (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0])
+ (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1])
* (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area;
if( rlen < 0.5 && rlen < rlenmin ) {
rlenmin = rlen;
cid = j;
}
}
if( cid >= 0 && wmarker_info[cid].cf < prev_info[i].marker.cf ) {
wmarker_info[cid].cf = prev_info[i].marker.cf;
wmarker_info[cid].id = prev_info[i].marker.id;
diffmin = 10000.0 * 10000.0;
cdir = -1;
for( j = 0; j < 4; j++ ) {
diff = 0;
for( k = 0; k < 4; k++ ) {
diff += (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0])
* (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0])
+ (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][2])
* (prev_info[i].marker.vertex[k][3] - wmarker_info[cid].vertex[(j+k)%4][4]);
}
if( diff < diffmin ) {
diffmin = diff;
cdir = (prev_info[i].marker.dir - j + 4) % 4;
}
}
wmarker_info[cid].dir = cdir;
}
}
for( i = 0; i < wmarker_num; i++ ) {
/*
printf("cf = %g\n", wmarker_info[i].cf);
*/
if( wmarker_info[i].cf < 0.5 ) wmarker_info[i].id = -1;
}
/*------------------------------------------------------------*/
for( i = j = 0; i < prev_num; i++ ) {
prev_info[i].count++;
if( prev_info[i].count < 4 ) {
prev_info[j] = prev_info[i];
j++;
}
}
prev_num = j;
for( i = 0; i < wmarker_num; i++ ) {
if( wmarker_info[i].id < 0 ) continue;
for( j = 0; j < prev_num; j++ ) {
if( prev_info[j].marker.id == wmarker_info[i].id ) break;
}
prev_info[j].marker = wmarker_info[i];
prev_info[j].count = 1;
if( j == prev_num ) prev_num++;
}
for( i = 0; i < prev_num; i++ ) {
for( j = 0; j < wmarker_num; j++ ) {
rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area;
if( rarea < 0.7 || rarea > 1.43 ) continue;
rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0])
* (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0])
+ (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1])
* (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area;
if( rlen < 0.5 ) break;
}
if( j == wmarker_num ) {
wmarker_info[wmarker_num] = prev_info[i].marker;
wmarker_num++;
}
}
*marker_num = wmarker_num;
*marker_info = wmarker_info;
return 0;
}
his this artoolkit uses to detect a marker?
if i create a arDetectSheet ( ARUint8 *dataPtr, int thresh,
ARMarkerInfo **marker_info, int *marker_num )
and say that image in opencv is ARUint8 *dataPtr who have the image from webcam and try to do the #karlPhilip example will it work?
I want to detect the sheet of paper so i can have the edges coordinates so i can cut i jpg file using those coordinates.
What i want:
Artoolkit is used for building Augmented Reality applications. It can't do what you described unless the piece of paper has something printed in it.
If you are considering some other framework to do this task, I suggest you invest in OpenCV.