This is my program to display a .x mesh. I am able to display the mesh tiger.x but not able to display ball.x. What is the difference between the two meshes? Is there something I should handle in the code? But I am able to view both the meshes using standard mesh viewers like the one which come with DirectX SDK.
Thanks.
but not able to display ball.x.
The question is unclear. Does the mesh load? Does it contain vertices/faces? Or maybe it crashes app? Or loading fails?
What is the difference between the two meshes?
The difference is that the second mesh (ball.x) doesn't include "templates".
I.e. this part:
template Header {
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
WORD major;
WORD minor;
DWORD flags;
}
template Vector {
<3D82AB5E-62DA-11cf-AB39-0020AF71E433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template Coords2d {
<F6F23F44-7686-11cf-8F52-0040333594A3>
FLOAT u;
FLOAT v;
}
template Matrix4x4 {
<F6F23F45-7686-11cf-8F52-0040333594A3>
array FLOAT matrix[16];
}
template ColorRGBA {
<35FF44E0-6C7C-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<D3E16E81-7835-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template IndexedColor {
<1630B820-7842-11cf-8F52-0040333594A3>
DWORD index;
ColorRGBA indexColor;
}
template Boolean {
<4885AE61-78E8-11cf-8F52-0040333594A3>
WORD truefalse;
}
template Boolean2d {
<4885AE63-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template MaterialWrap {
<4885AE60-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template TextureFilename {
<A42790E1-7810-11cf-8F52-0040333594A3>
STRING filename;
}
template Material {
<3D82AB4D-62DA-11cf-AB39-0020AF71E433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshFace {
<3D82AB5F-62DA-11cf-AB39-0020AF71E433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template MeshFaceWraps {
<4885AE62-78E8-11cf-8F52-0040333594A3>
DWORD nFaceWrapValues;
Boolean2d faceWrapValues;
}
template MeshTextureCoords {
<F6F23F40-7686-11cf-8F52-0040333594A3>
DWORD nTextureCoords;
array Coords2d textureCoords[nTextureCoords];
}
template MeshMaterialList {
<F6F23F42-7686-11cf-8F52-0040333594A3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material]
}
template MeshNormals {
<F6F23F43-7686-11cf-8F52-0040333594A3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template MeshVertexColors {
<1630B821-7842-11cf-8F52-0040333594A3>
DWORD nVertexColors;
array IndexedColor vertexColors[nVertexColors];
}
template Mesh {
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template FrameTransformMatrix {
<F6F23F41-7686-11cf-8F52-0040333594A3>
Matrix4x4 frameMatrix;
}
I.e. templates/structure declarations.
Also, in ball.x mesh is a part of hierarchy of Frames. In tiger.x it isn't, and is stored on top level of hierarchy.
It's been a while since I last used *.x file directly, but as far as I know, you'll need to include templates for all "non standard" templates into file. i.e. if file uses an object with template that wasn't registred using RegisterTemplates method of ID3DXFile or IDirectXFile, then the file won't load if template isn't written at the beginning of file. Try adding template definitions for every suspicious structure in ball.x , until you find the culprit . I'd start with "Header".
If the problem is because of hierarchy, you'll need to try another loading method.
using standard mesh viewers like the one which come with DirectX SDK.
AFAIK, mesh viewer comes with source code. Read the source and see how it works.
The mesh does not have any issue but the view. It was too zoomed in to display the image. I projected the image using the following matrix and was able to view the mesh properly.
//Set Projection
D3DXMATRIXA16 matProj(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,150.0);
Related
There is a directory with jpg files and one jpg file that should be compared with the files in the directory and in this way find 2 graphically identical files. It's about the simplest way. Maybe it is possible to compare the differences in R, G, B (variability), and not the R, G, B values themselves, since they may differ slightly with different degrees of jpeg compression.
for comparing 2 images:
Load the two jpgs into memory located bitmaps
see opening image file on c++ , PNG , JPEG for simple C++ Builder example just port to pascal the class names and usage should be the same in Delphi.
Compute abs differences
use Graphics::TBitmap::ScanLine[y] for fast pixel access, union or BYTE pointed for individual color channel access and compute abs average difference and max abs difference individually for each color channel.
for more info see TBitmap and ScanLine[y] usage and color channel access example
However as SilverWarior pointed out using RGB space is nto good for this so compare in luminance (just convert the RGB to luminance)
Threshold the result
simply if any of max and avg differences is bigger than some threshold the two images are not identical.
To create a list of files either use winapi FindFirst,FindNext,FindClose to obtain the directory list or use the file list from win3.11 VCL components set its directory and obtain the files in form of list...
And then just auto compare the images ...
Here small C++ builder example for comparing 2 images:
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#include <jpeg.hpp>
#pragma hdrstop
#include "win_main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;
Graphics::TBitmap *bmp0,*bmp1;
//---------------------------------------------------------------------------
int picture_load(Graphics::TBitmap *bmp,AnsiString name)
{
if (bmp==NULL) return 0;
if (!FileExists(name)) return 0;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
AnsiString ext=ExtractFileExt(name).LowerCase();
for(;;)
{
if (ext==".bmp")
{
bmp->LoadFromFile(name);
break;
}
if (ext==".jpg")
{
TJPEGImage *jpg=new TJPEGImage;
if (jpg==NULL) return 0;
jpg->LoadFromFile(name);
bmp->Assign(jpg);
delete jpg;
break;
}
return 0;
}
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
return 1;
}
//---------------------------------------------------------------------------
int picture_compare(Graphics::TBitmap *bmp0,Graphics::TBitmap *bmp1)
{
if ((bmp0==NULL)&&(bmp1==NULL)) return 1;
if (bmp0==NULL) return 0;
if (bmp1==NULL) return 0;
if (bmp0->Width !=bmp1->Width ) return 0;
if (bmp0->Height!=bmp1->Height) return 0;
int x,y,a;
double c0,c1,dc,de,maxdif=0.0,avgdif=0.0;
BYTE *p0,*p1;
for (y=0;y<bmp0->Height;y++)
{
p0=(BYTE*)bmp0->ScanLine[y];
p1=(BYTE*)bmp1->ScanLine[y];
for (a=0,x=0;x<bmp0->Width;x++)
{
c0 =p0[a]; c1 =p1[a]; a++; c0*=0.0722; c1*=0.0722; // B
c0+=p0[a]; c1+=p1[a]; a++; c0*=0.7152; c1*=0.7152; // G
c0+=p0[a]; c1+=p1[a]; a++; c0*=0.2126; c1*=0.2126; // R
a++; // A
dc=fabs(c0-c1);if (maxdif<dc) maxdif=dc; avgdif+=dc;
}
}
avgdif/=bmp0->Width;
avgdif/=bmp0->Height;
if (avgdif>10) return 0;
if (maxdif>50) return 0;
return 1;
}
//---------------------------------------------------------------------------
__fastcall TMain::TMain(TComponent* Owner) : TForm(Owner)
{
bmp0=new Graphics::TBitmap;
bmp1=new Graphics::TBitmap;
picture_load(bmp0,"in0.jpg");
picture_load(bmp1,"in1.jpg");
Caption=picture_compare(bmp0,bmp1);
int xs,ys;
xs=bmp0->Width+bmp1->Width;
ys=bmp0->Height;
if (ys<bmp1->Height) ys=bmp1->Height;
ClientWidth=xs;
ClientHeight=ys;
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormDestroy(TObject *Sender)
{
if (bmp0) delete bmp0; bmp0=NULL;
if (bmp1) delete bmp1; bmp1=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormPaint(TObject *Sender)
{
Canvas->Draw(0,0,bmp0);
Canvas->Draw(bmp0->Width,0,bmp1);
}
//---------------------------------------------------------------------------
You should play with the thresholds (I chose form very small input sample) to meet your needs and also beware this is comparing as grayscale images so you should add also some color comparison too (integrate some areas into avg color and compare that)
The function picture_compare returns true for "identical" images... beware it expects pf32bit pixelformat for both images !!! different format will change the pixel access and might also change the RGB order which will lead to wrong weights during conversion to luminance/grayscale. The pixelformat is set during picture_load so do not forget to set it if you use different loading method...
Also for comparing the color you might do a histogram for each color channel separately and compare that ...
I used double to prevent (32 bit) integer overflow of avgdif but take in mind for high resolution even double is not safe.
I'm binding a Shader Storage Buffer Object (SSBO) and use in the Fragment Shader. The bindings are fine, the buffer block is a multiple of vec4(4B) blocks as required by the specifications. However, the following code has an unexpected behavior. The variable 'datapoint' has the correct 'a' value, but the 'b,c,d' values are garbage.
I'm using an Nvidia Quadro K5000 with driver version 340.52.
struct data
{
int a;
float b;
float c;
float d;
};
// the same location '0' is used on the host
layout(std430, binding = 0) buffer MyBuffer
{
data mydata[];
}
data datapoint;
void main()
{
...
datapoint = mydata[some_index]; // some_index is withing range
...
}
In OpenCV I want to return the point position like Point(x,y) to the main() function that I click on the image in the mouse callback function . Is there anyway other than setting a global variable?
I don't want to write all the codes inside the on_mouse() function.
Thanks
to expand Safirs idea there, apart from a class or such, you could just pass in the point itself:
void on_mouse( int e, int x, int y, int d, void *ptr )
{
Point*p = (Point*)ptr;
p->x = x;
p->y = y;
}
Point p;
namedWindow("win");
setMouseCallback("win",on_mouse, (void*)(&p) );
// changed value of p will be accessible here
You can avoid using global variables by passing a pointer to your data as a parameter to setMouseCallback(). Agree with #berek, just wanted to show a full example below to avoid confusion about global variables.
using namespace cv;
void on_mouse( int e, int x, int y, int d, void *ptr )
{
Point*p = (Point*)ptr;
p->x = x;
p->y = y;
}
in main() {
Point p;
namedWindow("window");
Mat image = imread("someimage.jpg");
imshow(image);
//pass a pointer to `p` as parameter
setMouseCallback("window",on_mouse, &p );
// p will update with new mouse-click image coordinates
// whenever user clicks on the image window
}
No, this isn't possible, since the on_mouse() is a callback function. Here is the opencv documentation of it.
So, "global" variables are the only way to solve this problem. Alternatively, if you're looking for a nicer solution, you can create a wrapper class in which you have the namedWindow and the MouseCallback and a private member variable, which is manipulated when mouse callback function is called.
I'm confused by the OpenCV Mat element types. This is from the docs:
There is a limited fixed set of primitive data types the library can operate on.
That is, array elements should have one of the following types:
8-bit unsigned integer (uchar)
8-bit signed integer (schar)
16-bit unsigned integer (ushort)
16-bit signed integer (short)
32-bit signed integer (int)
32-bit floating-point number (float)
64-bit floating-point number (double)
...
For these basic types, the following enumeration is applied:
enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };
It's known that C++ standard doesn't define the size of basic types in bytes, so how do they use such assumptions? And what type should I expect from, let's say, CV_32S, is it int32_t or int?
Developing from Miki's answer,
In OpenCV 3 definition has moved to modules/core/include/opencv2/core/traits.hpp, where you can find:
/** #brief A helper class for cv::DataType
The class is specialized for each fundamental numerical data type supported by OpenCV. It provides
DataDepth<T>::value constant.
*/
template<typename _Tp> class DataDepth
{
public:
enum
{
value = DataType<_Tp>::depth,
fmt = DataType<_Tp>::fmt
};
};
template<int _depth> class TypeDepth
{
enum { depth = CV_USRTYPE1 };
typedef void value_type;
};
template<> class TypeDepth<CV_8U>
{
enum { depth = CV_8U };
typedef uchar value_type;
};
template<> class TypeDepth<CV_8S>
{
enum { depth = CV_8S };
typedef schar value_type;
};
template<> class TypeDepth<CV_16U>
{
enum { depth = CV_16U };
typedef ushort value_type;
};
template<> class TypeDepth<CV_16S>
{
enum { depth = CV_16S };
typedef short value_type;
};
template<> class TypeDepth<CV_32S>
{
enum { depth = CV_32S };
typedef int value_type;
};
template<> class TypeDepth<CV_32F>
{
enum { depth = CV_32F };
typedef float value_type;
};
template<> class TypeDepth<CV_64F>
{
enum { depth = CV_64F };
typedef double value_type;
};
In most of the cases/compilers you should be fine using C++ exact data types. You wouldn't have problems with single byte data types (CV_8U -> uint8_t and CV_8U -> int8_t) as unambiguously defined in C++. The same for float (32bit) and double (64bit). However, it is true that for other data types to be completely sure you use the correct data type (for example when using the at<> method) you should use for example:
typedef TypeDepth<CV_WHATEVER_YOU_USED_TO_CREATE_YOUR_MAT>::value_type access_type;
myMat.at<access_type>(y,x) = 0;
As a side note, I am surprised they decided to take such an ambiguous approach, instead of simply using exact data types.
Therefore, regarding your last question:
What type should I expect from, let's say, CV_32S?
I believe the most precise answer, in OpenCV 3, is:
TypeDepth<CV_32S>::value_type
In core.hpp you can find the following:
/*!
A helper class for cv::DataType
The class is specialized for each fundamental numerical data type supported by OpenCV.
It provides DataDepth<T>::value constant.
*/
template<typename _Tp> class DataDepth {};
template<> class DataDepth<bool> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<uchar> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<schar> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<char> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<ushort> { public: enum { value = CV_16U, fmt=(int)'w' }; };
template<> class DataDepth<short> { public: enum { value = CV_16S, fmt=(int)'s' }; };
template<> class DataDepth<int> { public: enum { value = CV_32S, fmt=(int)'i' }; };
// this is temporary solution to support 32-bit unsigned integers
template<> class DataDepth<unsigned> { public: enum { value = CV_32S, fmt=(int)'i' }; };
template<> class DataDepth<float> { public: enum { value = CV_32F, fmt=(int)'f' }; };
template<> class DataDepth<double> { public: enum { value = CV_64F, fmt=(int)'d' }; };
template<typename _Tp> class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; };
You can see that CV_32S is the value for the type int, not int32_t.
While C++ doesn't define the size of an element, the question is hypothetical: for systems OpenCV is run on, the sizes are known. Given
cv::Mat m(32,32,CV_32SC1, cv:Scalar(0));
std::cout << "size of the element in bytes: " << m.depth() << std::endl;
std::cout << "or " << m.step.p[ m.dims-1 ]/m.channels() << std::endl;
So how can you be sure it is int?
An attempt to call
int pxVal = m.at<int>(0,0);
will
CV_DbgAssert( elemSize()==sizeof(int) );
Where the left hand is defined via the cv::Mat::flags -- in this example as the predefined depth of the CV_32SC1 equal to
CV_DbgAssert( m.depth() == sizeof(int) )
or
CV_DbgAssert( 4 == sizeof(int) )
So if you succeeded you are left only the endianness. And that was checked when the cvconfig.h was generated (by CMake).
TL;DR, expect the types given in the header and you'll be fine.
You can find all definitions on your questions in opencv's sources.
See https://github.com/Itseez/opencv/blob/master/modules/core/include/opencv2/core/cvdef.h file.
I have found several #define in OpenCV's code related to CV_8UC1, CV_32SC1, etc. To make the enumerations work, OpenCV put additional codes to convert the plain numbers together as a parameter (i.e, CV_8UC1, CV_16UC2...are all represented by their respective numbers), and break the depth and channels apart in the definition of CvMat(I guess Mat may have similar codes in its definition). Then, it uses create() to allocate spaces for the matrix. Since create() is inline, I can only guess that it is similar to malloc() or something.
As source codes changes a lot from 2.4.9 to 3.0.0, I need to post more evidence later. Please allow me a little time to find out more and edit my answer.
In short the table you provided is correct.
If you want to directly access a pixel, you typecast it to the specifier to the right, for example CV_32S is a signed 32-bit.
The S always means a signed integral number (signed char, signed short, signed int)
The F always means a floating point number (float, double)
The U always means an unsigned integral number.
The enumeration is used only when creating or converting a Mat. It's a way of telling the mat which is the desired type, as I understand it it's the C predecessor to when templates were not used.
I use the C functionality exclusively, and in order to create an image, it would be an error to pass the following:
cvCreateImage(mySize,char, nChannels);
Instead, I pass the following:
cvCreateImage(mySize, IPL_DEPTH_8U, nChannels);
Here, the IPL_DEPTH_8U is a flag that is used by the function. The function itself has a switch-type statement that checks the flag. The actual value of the flag is most often meaningless as it's most often controlled by conditional, not algebraic statements.
I'm newer to C++. I have written some code, but when i run it, there's always this:
raised exception class
EAccessViolation with message 'Access
violation at address'
i don't understand this. Would you like to help me solve it? It's important to me. Really, really thank you!
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <conio.h>
#define k 2
#define minoffset 0.5
using namespace std;
struct Point
{
double X;
double Y;
};
vector<Point> dataprocess();
void k_means(vector<Point> points,int N);
double getdistance(Point p1,Point p2)
{ double distance;
distance=sqrt((p1.X-p2.X)*(p1.X-p2.X)+(p1.Y-p2.Y)*(p1.Y-p2.Y));
return distance;
}
int getmindis(Point p,Point means[])
{
int i;
int c;
double dis=getdistance(p,means[0]);
for(i=1;i<k;i++)
{
double term=getdistance(p,means[i]);
if(term<dis)
{
c=i;
dis=term;
}
}
return c;
}
Point getmeans(vector<Point> points)
{
int i;
double sumX,sumY;
Point p;
int M=points.size();
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
p.X=sumX/M;
p.Y=sumY/M;
return p;
}
int main()
{ int N;
vector<Point> stars;
stars=dataprocess();
N=stars.size();
cout<<"the size is:"<<N<<endl;
k_means(stars,N);
getch();
}
vector<Point> dataprocess()
{
int i;
int N;
double x,y;
vector<Point> points;
Point p;
string import_file;
cout<<"input the filename:"<<endl;
cin>>import_file;
ifstream infile(import_file.c_str());
if(!infile)
{
cout<<"read error!"<<endl;
}
else
{
while(infile>>x>>y)
{
p.X=x;
p.Y=y;
points.push_back(p);
}
}
N=points.size();
cout<<"output the file data:"<<endl;
for(i=0;i<N;i++)
{
cout<<"the point"<<i+1<<"is:X="<<points[i].X<<" Y="<<points[i].Y<<endl;
}
return points;
}
void k_means(vector<Point> points,int N)
{
int i;
int j;
int index;
vector<Point> clusters[k];
Point means[k];
Point newmeans[k];
double d,offset=0;
bool flag=1;
cout<<"there will be"<<k<<"clusters,input the original means:"<<endl;
for(i=0;i<k;i++)
{
cout<<"k"<<i+1<<":"<<endl;
cin>>means[i].X>>means[i].Y;
}
while(flag)
{
for(i=0;i<N;i++)
{
index=getmindis(points[i],means);
clusters[index].push_back(points[i]);
}
for(j=0;j<k;j++)
{
newmeans[j]=getmeans(clusters[j]);
offset=getdistance(newmeans[j],means[j]);
}
if(offset>d)
{
d=offset;
}
flag=(minoffset<d)?true:false;
for(i=0;i<k;i++)
{
means[i]=newmeans[i];
clusters[i].clear();
}
}
for(i=0;i<k;i++)
{
cout<<"N"<<i+1<<"="<<clusters[i].size()<<endl;
cout<<"the center of k"<<i+1<<"is:"<<means[i].X<<" "<<means[i].Y<< endl;
}
}
You surely have some algo errors in you code. It is difficult to deal with code without input data, that caused an error, but let's try:
First, lets look at function Point getmeans(vector<Point> points)
it is supposed to evaluate mean coordinates for cluster of points: if you pass an empty cluster to this function it will cause an error:
look here -
int M=points.size()
and here -
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
if your cluster is empty than M will be zero and you loop will iterate 2^31 times (until 32 bit integer overflow) and each time you will try to read values of nonexistent vector items
So, You have to test if you vector is not empty before running main function loop and you have to decide which mean values should be assigned for zero cluster (May be you need an additional flag for empty cluster which will be checked before dealing with cluster's mean values)
Then lets examine function int getmindis(Point p,Point means[]) and, also, a place, where we call it:
index=getmindis(points[i],means); clusters[index].push_back(points[i]);
This function assings points to clusters. cluster number is ruled by c variable. If input point doesn't fit to any cluster, function will return uninitialized variable (holding any possible value) which. then is used as vector index of nonexisting element - possible access violation error
You probably have to initialize c to zero in declaration
Tell us when you will be ready with errors described above and also show us a sample input file (one which causes errors, if all datasets cause errors, show us the smallest one)