rodakina_s Δημοσ. 30 Μαΐου 2010 Δημοσ. 30 Μαΐου 2010 κατ'αρχην καλησπερα! εχω τις δυο παρακάτω συναρτησεις οπου η πρώτη παιρνει μια .bmp ( bitmap ) εικονα την φορά ( δηλαδη την εκτελω στην main δυο φορες για δυο διαφορετικες εικονες ετσι ωστε να την μετατρεψει σε hex ( δεκαεξαδικο ) ) και τις αποθηκευει σε δυο διαφορετικα αρχεια file1.txt και file2.txt , ενω η δευτερη συναρτηση "διαβάζει" την καθε γραμμη του κάθε αρχειου και τα συγκρινει αν ειναι ίδια και εμφανιζει αντιστοιχως το ανάλογο μηνυμα. > void PhotoClass::extractHexFile(char *filename,char *img) { int byte = 0; int start; FILE *fp = fopen(filename,"r"); //open file for reading do fgetc(fp); while (++byte < 10); fread(&start,4,1,fp); byte += 4; do fgetc(fp); while (++byte < start); fread(img,1,9600,fp); fclose(fp); } bool PhotoClass::crateHexFile(char *fileName,char *outFile){ int i; int j; char hexdigit[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; FILE *fp = fopen(outFile,"w"); //unsigned char *bitmap = (unsigned char *)malloc(9600); char *bitmap = (char *)malloc(9600); //assign 9600 bytes of memory to the pointer 'bitmap' extractHexFile(fileName,bitmap); fputs("const unsigned char bitmap[] = \n{",fp); for (i=239; i >= 0; i--) //start at bottom, and work up in rows { fputc('\n',fp); //each line, put a return for (j = 0; j < 40; j++) { fputc('0',fp); fputc('x',fp); //put the '0x' in front of the hex value fputc(hexdigit[ (bitmap[(i*40)+j]>>4)&0x0F ],fp); //put the upper //value of the byte fputc(hexdigit[bitmap[(i*40)+j]&0x0F],fp); //put the lower value of the //byte if (!((i==1)&&(j==39))) fputc(',',fp); } } fputs("\n}\n",fp); fclose(fp); free(bitmap); } bool PhotoClass::comparePhotos(){ int count=0; ifstream ifs1("outFile1.c"); ifstream ifs2("outFile2.c"); ofstream ofs("result.txt"); string line1; string line2; while ((!ifs2.eof())&&(!ifs1.eof())) { getline(ifs1,line1); getline(ifs2,line2); if ( line1 == line2 ) { cout << endl << metr << "EINAI IDIES"; } else { cout << endl << metr << "EINAI DIAFORETIKES"; } metr++; } } Το προβλημα που αντιμετωπιζω ειναι: 1) Πως γινεται καθε φορα που εκτελω το πρόγραμμα να μετατρεπει με διαφορετικο τροπο ( δηλαδη διαφορετικους δεκαεξαδικους χαρακτηρες ) την καθε .bmp εικόνα ενω η εικονα ειναι η ιδια ? ? ? ? ( ποιο το λάθος του αλγορίθμου δηλαδή ? ) 2) Και μια πληροφορία σχετικά με το μέγεθος της εικόνας που θέλω να σιγουρευτώ ειναι αν μπορώ να χρησιμοποιησω τον αλγοριθμο αυτο σε εικόνα 320 χ 240 ? Επισυναπτω και το παρακάτω για να γνωριζεται την μορφη του αρχειου με την μετατροπη σε δεκαεξαδικους αριθμούς. > const unsigned char bitmap[] = { 0xFD,0xDD,0xD0,0xFF,0xE2,0xD5,0xFF 0x4B,0xBC,0x84,0x6D,0xEB,0xB9,0x9B 0x5E,0x4A,0x59,0x46,0x31,0x5B,0x48 0xF9,0xDC,0xD3,0xF6,0xD9,0xD0,0xEA 0xD3,0xFD,0xDE,0xD3,0xFA,0xDB,0xCA 0xCF,0xBA,0xFF,0xCF,0xB8,0xFF,0xCC ....... ....... ....... ....... } Can you help me please???
V.I.Smirnov Δημοσ. 30 Μαΐου 2010 Δημοσ. 30 Μαΐου 2010 Μακροσκοπικά μιλώντας, 1) το αποτέλεσμα δεν μπορεί να είναι διαφορετικό εφόσον η ρουτίνα καλείται με τα ίδια ορίσματα. Σίγουρα την δεύτερη φορά την καλείς ή διαβάζει εκ παραδρομής διαφορετικά δεδομένα. Δεν μας δίνεις τον πλήρη κώδικα για να πειραματιστούμε. 2) Αν έχεις υπολογίσει σωστά το απαιτούμενο ποσό μνήμης δεν υπάρχει πρόβλημα μεγέθους. Χμ...320x240/8=9600. Αλλά απ΄ότι βλέπω υποθέτεις header με μέγεθος 14 bytes δηλ. θεωρείς ότι το bmp είναι στην πιο παλιά μορφή (OS/2 style). Αν αυτό που διαβάζεις δεν είναι, τότε δεν το διαβάζεις σωστά. Η πιο συνήθης μορφή έχει header με μέγεθος 40 bytes και μπορεί να έχει και color table. Σιγουρέψου ότι διαβάζεις το αναμενόμενο. Η μετατροπή και η σύγκριση δείχνουν σωστές αλλά χωρίς να το τρέξουμε μπορεί να μας διαφεύγουν πολλά... Τα DIBS αναλύονται διεξοδικά στο βιβλίο "Programming Windows" κεφ. 15 του Petzold. Επίσης, το βιβλίο "Windows 2000 Graphics API" έχει το κεφ. 7 αφιερωμένο στα DIBS. Από το πρώτο είχα διαβάσει κάποτε την δομή του header και του αρχείου - είναι αρκετά πολύπλοκος. Το δεύτερο δίνει πρακτικές εξηγήσεις και ρουτίνες για ανάγνωση, γραφή και δημιουργία DIBS. Δεν τα θυμάμαι τώρα, δυστυχώς. Σου συνιστώ να διαβάσεις απο εκεί - θα λύσεις όλες τις απορίες σου για τα .bmp.
rodakina_s Δημοσ. 30 Μαΐου 2010 Μέλος Δημοσ. 30 Μαΐου 2010 Η main ειναι: > //--------------------------------------------------------------------------- #include <vcl.h> #include <Vfw.h> #include <iostream.h> #pragma hdrstop #include "PhotoClass.h" #include <tchar.h> void extractHexFile(char *filename,char *img) { int byte = 0; int start; FILE *fp = fopen(filename,"r"); //open file for reading do fgetc(fp); while (++byte < 10); fread(&start,4,1,fp); byte += 4; do fgetc(fp); while (++byte < start); fread(img,1,9600,fp); fclose(fp); } bool crateHexFile(char *fileName,char *outFile){ int i; int j; char hexdigit[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; FILE *fp = fopen(outFile,"w"); //unsigned char *bitmap = (unsigned char *)malloc(9600); char *bitmap = (char *)malloc(9600); //assign 9600 bytes of memory to the pointer 'bitmap' extractHexFile(fileName,bitmap); fputs("const unsigned char bitmap[] = \n{",fp); for (i=239; i >= 0; i--) //start at bottom, and work up in rows { fputc('\n',fp); //each line, put a return for (j = 0; j < 40; j++) { fputc('0',fp); fputc('x',fp); //put the '0x' in front of the hex value fputc(hexdigit[ (bitmap[(i*40)+j]>>4)&0x0F ],fp); //put the upper value of the byte fputc(hexdigit[bitmap[(i*40)+j]&0x0F],fp); //put the lower value of the byte if (!((i==1)&&(j==39))) fputc(',',fp); } } fputs("\n}\n",fp); fclose(fp); free(bitmap); } bool comparePhotos(){ int count=0; ifstream ifs1("outFile1.c"); ifstream ifs2("outFile2.c"); ofstream ofs("result.txt"); string line1; string line2; int metr=0; while ((!ifs2.eof())&&(!ifs1.eof())) { getline(ifs1,line1); getline(ifs2,line2); if ( line1 == line2 ) {//an einai idia den emfanizei tipota cout << endl << metr << "EINAI IDIES"; //ofs << line1; //ofs << "\n"; } else {cout << endl << metr << "EINAI DIAFORETIKES"; count=1; //break; } metr++; } getchar(); } //--------------------------------------------------------------------------- #pragma argsused int _tmain(int argc, _TCHAR* argv[]) { crateHexFile("p1.bmp","outFile1.c"); crateHexFile("p2.bmp","outFile2.c"); comparePhotos(); return 0; } ΓΕΝΙΚΑ αυτός ειναι ο κωδικας νομιζω συμπερασματα βγαινουν .... HEEEEEELLLLLLLPPPPP :cry::cry::cry:
yourse.gr Δημοσ. 30 Μαΐου 2010 Δημοσ. 30 Μαΐου 2010 Χωρίς να ελέγξω ιδιαίτερα τον κώδικά σου ( δηλαδή μπορεί αυτό να μην είναι το μόνο πρόβλημα ) ... Αφού είναι εικόνες το >FILE *fp = fopen(filename,"r"); πρέπει να γίνει >FILE *fp = fopen(filename,"rb");
rodakina_s Δημοσ. 30 Μαΐου 2010 Μέλος Δημοσ. 30 Μαΐου 2010 Για να ειμαστε πιο οργανωμενοι εχω την παρακατω κλαση: main.cpp >//--------------------------------------------------------------------------- #include <vcl.h> #include <Vfw.h> #include <iostream.h> #pragma hdrstop #include "PhotoClass.h" #include <tchar.h> //--------------------------------------------------------------------------- #pragma argsused int _tmain(int argc, _TCHAR* argv[]) { PhotoClass v; v.capCreCapWin(); v.crateHexFile("p1.bmp","outFile1.c"); v.crateHexFile("p2.bmp","outFile2.c"); Sleep(1000); v.comparePhotos(); return 0; } //--------------------------------------------------------------------------- PhotoClass.cpp > //--------------------------------------------------------------------------- #pragma hdrstop #include "PhotoClass.h" PhotoClass::PhotoClass(){ strcpy(photo[0],"p1"); strcpy(photo[1],"p2"); /* Δημιουργεί ενα παράθυρο για φωτο σε περιπτωση επιτυχίας επιστρέφει τον HANDLE διαφορετικα επιστρεφει ΝULL */ hWndC = capCreateCaptureWindow ( (LPSTR) "My Capture Window", // ονομα παραθύρου WS_SIZEBOX, // style παραθυρου ( αχρηστο ) 0, 0, 10, 10, // window position and dimensions ( βλακεια ) NULL, 0 /* child ID */); ans=capDriverConnect(hWndC,0); cout << endl << "einai:" << ans; if(hWndC!=NULL) { cout << "capCreateCaptureWindow EXIST !" ; } else { cout << "capCreateCaptureWindow PROBLEM !" ; // exit(1); } } PhotoClass::~PhotoClass(){ capDriverDisconnect(hWndC); capPreview(hWndC, FALSE); } HWND PhotoClass::capCreCapWin(void){ int i=0; while(i<2){ capGrabFrame(hWndC); capEditCopy(hWndC); capOverlay(hWndC, TRUE); if(capFileSaveDIB(hWndC, strcat(photo[i],".bmp"))){ cout << endl << "OK SAVE FILE!"; } else{ cout << endl << "Problem"; } i++; Sleep(1000); } } //οριζει το χρονικο διαστημα για καθε νεο frame. void PhotoClass::capPreRate(HWND hWndC_){ hWndC = hWndC_; if(capPreviewRate(hWndC, 5000)){ // rate, in milliseconds cout << endl << "capPreviewRate EXIST!"; } else{ cout << endl << "capPreviewRate Problem"; } } void PhotoClass::extractHexFile(char *filename,char *img) { int byte = 0; int start; FILE *fp = fopen(filename,"r"); //open file for reading do fgetc(fp); while (++byte < 10); fread(&start,4,1,fp); byte += 4; do fgetc(fp); while (++byte < start); fread(img,1,9600,fp); fclose(fp); } bool PhotoClass::crateHexFile(char *fileName,char *outFile){ int i; int j; char hexdigit[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; FILE *fp = fopen(outFile,"w"); //unsigned char *bitmap = (unsigned char *)malloc(9600); char *bitmap = (char *)malloc(9600); //assign 9600 bytes of memory to the pointer 'bitmap' extractHexFile(fileName,bitmap); fputs("const unsigned char bitmap[] = \n{",fp); for (i=239; i >= 0; i--) //start at bottom, and work up in rows { fputc('\n',fp); //each line, put a return for (j = 0; j < 40; j++) { fputc('0',fp); fputc('x',fp); //put the '0x' in front of the hex value fputc(hexdigit[ (bitmap[(i*40)+j]>>4)&0x0F ],fp); //put the upper value of the byte fputc(hexdigit[bitmap[(i*40)+j]&0x0F],fp); //put the lower value of the byte if (!((i==1)&&(j==39))) fputc(',',fp); } } fputs("\n}\n",fp); fclose(fp); free(bitmap); } bool PhotoClass::comparePhotos(){ int count=0; ifstream ifs1("outFile1.c"); ifstream ifs2("outFile2.c"); ofstream ofs("result.txt"); string line1; string line2; int metr=0; while ((!ifs2.eof())&&(!ifs1.eof())) { getline(ifs1,line1); getline(ifs2,line2); if ( line1 == line2 ) {//an einai idia den emfanizei tipota cout << endl << metr << "EINAI IDIES"; //ofs << line1; //ofs << "\n"; } else {cout << endl << metr << "EINAI DIAFORETIKES"; count=1; //break; } metr++; } getchar(); } //--------------------------------------------------------------------------- #pragma package(smart_init) PhotoClass.h > //--------------------------------------------------------------------------- #ifndef VideoH #define VideoH #include <iostream> #include <windows.h> #include <fstream> #include <string> #include <vcl.h> #include <Vfw.h> using namespace std; class PhotoClass{ private: HWND hWndC; bool ans; char photo[11][8]; public: PhotoClass(); ~PhotoClass(); HWND capCreCapWin(void); void capPreRate(HWND hWndC_); bool crateHexFile(char *fileName,char *outFile); void extractHexFile(char *filename,char *img); bool comparePhotos(); }; //--------------------------------------------------------------------------- #endif /* ΔΗΜΙΟΥΡΓΕΙ ΤΟ ΠΑΡΑΘΥΡΟ ΔΙΑΛΟΓΟΥ ΓΙΑ ΡΥΘΜΙΣΕΙΣ ΤΗΣ ΦΩΤΟ CAPDRIVERCAPS CapDrvCaps; capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS)); // Video source dialog box. if (CapDrvCaps.fHasDlgVideoSource) capDlgVideoSource(hWndC); // Video format dialog box. if (CapDrvCaps.fHasDlgVideoFormat) { capDlgVideoFormat(hWndC); // Are there new image dimensions? capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); // If so, notify the parent of a size change. } // Video display dialog box. if (CapDrvCaps.fHasDlgVideoDisplay) capDlgVideoDisplay(hWndC); /* ΤΕΛΟΣ ΤΕΛΟΣ */ /* ΤΟΠΟΘΕΤΕΙ ΤΙΣ ΠΑΡΑΜΕΤΡΟΥΣ ΤΟΥ ΠΑΡΑΘΥΡΟΥ CAPSTATUS CapStatus; capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth, CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE); ΤΕΛΟΣ SetWindowPos ΤΕΛΟΣ*/ /* char szCaptureFile[] = "MYCAP.AVI"; capFileSetCaptureFile( hWndC, szCaptureFile); capFileAlloc( hWndC, (1024L * 1024L * 5)); */ /* Βρισκει ποιους και πόσους drivers εχουμε εγκατεστημένους και μπορούμε αν εχουμε πολλούς να επιλέξουμε ποιον θέλουμε char szDeviceName[80]; char szDeviceVersion[80]; for (int wIndex = 0; wIndex < 10; wIndex++) { if (capGetDriverDescription( wIndex, szDeviceName, sizeof (szDeviceName), szDeviceVersion, sizeof (szDeviceVersion) )) { cout << endl << "The driver is:" << szDeviceName << endl << "The Version is:" << szDeviceVersion; break; } else { cout << endl << "Problem with capGetDriverDescription"; } } Τελος capGetDriverDescription ΤΕΛΟΣ*/ /* /* Σύνδεση με τον driver capDriverConnect(hWndC,0); //Handle , περιεχομενα του driver 0 εως 9 ( δεν ξερω τι κανει!! ) /* capDriverDisconnect (hWndC); αποσυνδεει τον Handle */ /* ΤΕΛΟΣ capDriverConnect ΤΕΛΟΣ */ Αυτος ειναι ο κωδικας και γραφτηκε στον embarcadero Rad studio 2010 , C++ εχει και ορισμενα σχόλια αν σας βοηθησουν καλως... :fear::fear::fear::fear:
V.I.Smirnov Δημοσ. 30 Μαΐου 2010 Δημοσ. 30 Μαΐου 2010 To πρώτο απόσπαμα που έδωσες έχει αρκετά συντακτικά λάθη. Πχ. οι συναρτήσεις crateHexFile και comparePhotos δηλώνονται bool αλλά δεν επιστρέφουν τίποτε (λάθος). Εσένα δεν σου χτυπάει ; Το διόρθωσα και τώρα κάνει compile (visual studio 2008). Αυτό είναι : >#include <fstream> #include <iostream> #include <string> using namespace std; void extractHexFile(char *filename,char *img) { int byte = 0; int start; FILE *fp = fopen(filename,"r"); //open file for reading do fgetc(fp); while (++byte < 10); fread(&start,4,1,fp); byte += 4; do fgetc(fp); while (++byte < start); fread(img,1,9600,fp); fclose(fp); } void crateHexFile(char *fileName,char *outFile){ int i; int j; char hexdigit[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; FILE *fp = fopen(outFile,"w"); //unsigned char *bitmap = (unsigned char *)malloc(9600); char *bitmap = (char *)malloc(9600); //assign 9600 bytes of memory to the pointer 'bitmap' extractHexFile(fileName,bitmap); fputs("const unsigned char bitmap[] = \n{",fp); for (i=239; i >= 0; i--) //start at bottom, and work up in rows { fputc('\n',fp); //each line, put a return for (j = 0; j < 40; j++) { fputc('0',fp); fputc('x',fp); //put the '0x' in front of the hex value fputc(hexdigit[ (bitmap[(i*40)+j]>>4)&0x0F ],fp); //put the upper value of the byte fputc(hexdigit[bitmap[(i*40)+j]&0x0F],fp); //put the lower value of the byte if (!((i==1)&&(j==39))) fputc(',',fp); } } fputs("\n}\n",fp); fclose(fp); free(bitmap); } void comparePhotos(){ int count=0; ifstream ifs1("outFile1.txt"); ifstream ifs2("outFile2.txt"); string line1; string line2; int metr=0; while ((!ifs2.eof())&&(!ifs1.eof())) { getline(ifs1,line1); getline(ifs2,line2); if ( line1 == line2 ) {//an einai idia den emfanizei tipota cout << endl << metr << "EINAI IDIES"; //ofs << line1; //ofs << "\n"; } else {cout << endl << metr << "EINAI DIAFORETIKES"; count=1; //break; } metr++; } getchar(); } int main() { crateHexFile("p1.bmp","outFile1.c"); crateHexFile("p2.bmp","outFile2.c"); comparePhotos(); return 0; } Αλλά για να δοκιμάσουμε πρέπει να έχουμε και δυο εικόνες σαν αυτές που αναμμένει να διαβάσει (bmp 320x240 ΟS/2 style). Εφόσον το λάθος είναι εδώ, μπορείς κι' εσύ να το ψάξεις χρησιμοποιώντας breakpoints...
rodakina_s Δημοσ. 31 Μαΐου 2010 Μέλος Δημοσ. 31 Μαΐου 2010 Οχι σε εμενα δεν χτυπαει αλλα και παλι μικρο το λαθος. ΠΟΥ ΕΙΝΑΙ ΤΟ ΛΑΘΟΣ ? ? ? ? ? :cry::cry::cry:
V.I.Smirnov Δημοσ. 31 Μαΐου 2010 Δημοσ. 31 Μαΐου 2010 Οχι σε εμενα δεν χτυπαει αλλα και παλι μικρο το λαθος. ΠΟΥ ΕΙΝΑΙ ΤΟ ΛΑΘΟΣ ? ? ? ? ? Μικρό, ξε-μικρό, δώστο σωστά να μην παιδευόμαστε όσοι το δούμε. Για λογικά λάθη ρωτάς κι όχι για συντακτικά. Να μην παιδευόμαστε για το αυτονόητο. Με απλή εποπτεία του κώδικα είναι δύσκολο να φανεί αν και τι πηγαίνει στραβά. Όπως διόρθωσα το απόσπασμα τρέχει αυτοτελώς. Μπορεί να το πάρει κάποιος πιο έμπειρος και να ψάξει τι γίνεται. Αλλά, έγραψα ήδη, πρέπει να έχουμε ως δεδομένα δυο εικόνες όπως αυτές που διαβάζει : δύο bmp αρχεία 320x240 OS/2 style. Πού είναι ; Σου υπενθυμίζω επίσης ότι αυτή είναι η παλιά μορφή bmp η οποία δεν ξέρω κατά πόσον συναντάται σήμερα. Συνήθως τα προγράμματα σώζουν στην μορφή extended bitmap που έχει header με 40 bytes. Πού να ψάχνουμε τώρα τις σωστές εικόνες για να κάνουμε δοκιμές... Εσύ που τις έχεις πρέπει να τις δώσεις ή να το βρεις μόνος σου με breakpoints...
rodakina_s Δημοσ. 31 Μαΐου 2010 Μέλος Δημοσ. 31 Μαΐου 2010 Οκ εχεις δικιο. Αλλά επειδη δεν ξερω για τις εικονες που λες θα σου πω μονο οτι χρησιμοποιω την webcam μου και τις αποθηκευει σε .bmp . . . . ( Λες εκει να ειναι το προβλημα ? ) Για να σου δωσω να καταλαβεις θελω να μετατρεπει το προγραμμα δυο εικονες σε hex και μετα να συγκρινω τα δυο αυτα πλήθη!! δεκαεξαδικων αριθμων για να δω αν κουνηθηκε κατι μπροστα απο την webcam δηλαδη αν υπηρξε κινηση!! Αν εχεις σκεφτει καποιο αλλο τροπο να το επιτυχω ....
bnvdarklord Δημοσ. 31 Μαΐου 2010 Δημοσ. 31 Μαΐου 2010 Μμμ αν θες να συγκρίνεις εικόνες απο webcam δεν ξερω κατα πόσο είναι αποδοτικός ο τρόπος, γιατι το εβαλα να τρέξει τωρα εδώ και 5 λεπτά και ακομα δεν εχει τελειωσει(βεβαια εχω εναν παμπάλαιο celeron cpu αλλα anyway...) edit: μολις διαπίστωσα οτι συγκρίνεις τα αρχεια outFile.txt ενώ δημιουργείς αρχεία outFile.c edit2: μετα την διορθωση στο edit1 τελειωνει αμεσως, αλλα ενω εβαλα 2 διαφορετικες εικόνες μου τις βγαζει ιδιες...
rodakina_s Δημοσ. 31 Μαΐου 2010 Μέλος Δημοσ. 31 Μαΐου 2010 Το .txt και το .c ειναι λεθος στην αντιγραφη μην το υπολογιζεις αλλα διορθωσε το. Δεν εχει κανεις ετοιμο κωδικα που να κανει την δουλεια μου ???? θα σκασω που κολλαω σε τετοια πραγματακια και δεν μπορω να συνεχισω....
Evgenios1 Δημοσ. 31 Μαΐου 2010 Δημοσ. 31 Μαΐου 2010 Οκ εχεις δικιο. Αλλά επειδη δεν ξερω για τις εικονες που λες θα σου πω μονο οτι χρησιμοποιω την webcam μου και τις αποθηκευει σε .bmp . . . . ( Λες εκει να ειναι το προβλημα ? ) Για να σου δωσω να καταλαβεις θελω να μετατρεπει το προγραμμα δυο εικονες σε hex και μετα να συγκρινω τα δυο αυτα πλήθη!! δεκαεξαδικων αριθμων για να δω αν κουνηθηκε κατι μπροστα απο την webcam δηλαδη αν υπηρξε κινηση!! Αν εχεις σκεφτει καποιο αλλο τροπο να το επιτυχω .... Δεν υπαρχει νοημα να κανεις ενα bmp format σε ενα text format για μια συγκριση. Προχειρα* μπορεις να κανεις.( Εαν το αρχειο αρχιζει με "BM") seek στο 34 και διβαζεις εναν uint που ειναι το μεγεθος του raw seek στο 10 και διβαζεις εναν uint που σου λεει που ειναι η αρχη του raw φτιαχνεις εναν buffer με μεγεθος του raw seek στην αρχη του raw και διαβαζεις. το ιδιο και για το δευτερο αρχειο. Εφοσον εχεις δυο buffer σου μενει να κανεις εναν αλγοριθμο με τον οποιο μπορεις να διαπιστωσεις μια "κινηση", προχειρη λυση να κανεις συγκριση +-5 ποσοστου λαθους λογου web cam. Τελος νομιζω καποιος εδω εχει γραψει ενα προγραμμα το οποιο ανιχνευει κινηση απο τη web cam αλλα δε θυμαμαι ποιος . Edit: Το βρηκα, εδω εισαι Edit1: Εισαι και κωλοφαρδος, εχει το ιδιο IDE με σενα lol.
V.I.Smirnov Δημοσ. 31 Μαΐου 2010 Δημοσ. 31 Μαΐου 2010 Οκ εχεις δικιο. Αλλά επειδη δεν ξερω για τις εικονες που λες θα σου πω μονο οτι χρησιμοποιω την webcam μου και τις αποθηκευει σε .bmp . . . . ( Λες εκει να ειναι το προβλημα ? ) Για να σου δωσω να καταλαβεις θελω να μετατρεπει το προγραμμα δυο εικονες σε hex και μετα να συγκρινω τα δυο αυτα πλήθη!! δεκαεξαδικων αριθμων για να δω αν κουνηθηκε κατι μπροστα απο την webcam δηλαδη αν υπηρξε κινηση!! Αν εχεις σκεφτει καποιο αλλο τροπο να το επιτυχω .... To θέμα είναι ότι και αν ακόμη τις διαβάζει λάθος θα πρέπει να δίνει το ίδιο μύνημα και τις δυο φορές εφόσον πρόκειται για την ίδια ακριβώς εικόνα. Αυτό δεν ρώτησες αρχικά ; Από κει και πέρα για να κάνεις σωστή δουλειά πρέπει να βεβαιωθείς ότι η μορφή bmp που σώζει η κάμερα είναι πράγματι αυτή που επιχειρείς να διαβάσεις διότι όπως σου είπα υπάρχουν 2-3 παραλλαγές στα bmp (στα windows λέγονται DIB). Το να διαβάσεις είναι πιο δύσκολο από το να γράψεις διότι στο γράψιμο επιλέγεις εσύ την παραλλαγή και η ρουτίνα έχει συγκεκριμένη μορφή ενώ για το διάβασμα δεν ξέρεις με ποιά παραλλαγή σώθηκε. Για την σύγκριση που λες, υπάρχουν πιο καλοί τρόποι από το να κάνεις μετατροπή και σύγκριση των αρχείων στο δίσκο. Πχ. έστω ότι λαμβάνονται δυο bmps. Άρα έχεις τους δείκτες στα block μνήμης όπoυ έχουν φορτωθεί και συγκρίνεις άμεσα αυτά τα δυο block... Παίζει ρόλο και πώς δουλεύει η camera. Αν μπορείς να λάβεις την εικόνα κατευθείαν στη μνήμηα γιατί να σώζεις κάθε frame στο δίσκο που είναι πολύ πιο χρονοβόρο ; Υπάρχουν και πιο πολύπλοκοι τρόποι αλλά πρέπει να ασχοληθείς με επεξεργασία εικόνας. Πχ. βρίσκεις το ιστόγραμμα της εικόνας, εντοπίζεις ακμές κ.α. Υ.Γ. O Eygenios1 το έθεσε σωστά. Εφόσον κάνεις μόνον σύγκριση δεν χρειάζονται μετατροπές. Και σωστά λέει ότι ένα bmp αρχίζει με 'ΒΜ'. Σου ξαναλέω όμως ότι το header μπορεί να έχει μέγεθος 40 bytes κι όχι 14 και να έχει επιπλέον και ένα color table. Η σωστή ανάγνωση είναι απαραίτητη αν επιχειρήσεις και κάτι άλλο διότι τότε χρειάζεσαι πραγματικά την εικόνα.
rodakina_s Δημοσ. 31 Μαΐου 2010 Μέλος Δημοσ. 31 Μαΐου 2010 To θέμα είναι ότι και αν ακόμη τις διαβάζει λάθος θα πρέπει να δίνει το ίδιο μύνημα και τις δυο φορές εφόσον πρόκειται για την ίδια ακριβώς εικόνα. Αυτό δεν ρώτησες αρχικά ; Από κει και πέρα για να κάνεις σωστή δουλειά πρέπει να βεβαιωθείς ότι η μορφή bmp που σώζει η κάμερα είναι πράγματι αυτή που επιχειρείς να διαβάσεις διότι όπως σου είπα υπάρχουν 2-3 παραλλαγές στα bmp (στα windows λέγονται DIB). Το να διαβάσεις είναι πιο δύσκολο από το να γράψεις διότι στο γράψιμο επιλέγεις εσύ την παραλλαγή και η ρουτίνα έχει συγκεκριμένη μορφή ενώ για το διάβασμα δεν ξέρεις με ποιά παραλλαγή σώθηκε. Για την σύγκριση που λες, υπάρχουν πιο καλοί τρόποι από το να κάνεις μετατροπή και σύγκριση των αρχείων στο δίσκο. Πχ. έστω ότι λαμβάνονται δυο bmps. Άρα έχεις τους δείκτες στα block μνήμης όπoυ έχουν φορτωθεί και συγκρίνεις άμεσα αυτά τα δυο block... Παίζει ρόλο και πώς δουλεύει η camera. Αν μπορείς να λάβεις την εικόνα κατευθείαν στη μνήμηα γιατί να σώζεις κάθε frame στο δίσκο που είναι πολύ πιο χρονοβόρο ; Υπάρχουν και πιο πολύπλοκοι τρόποι αλλά πρέπει να ασχοληθείς με επεξεργασία εικόνας. Πχ. βρίσκεις το ιστόγραμμα της εικόνας, εντοπίζεις ακμές κ.α. Υ.Γ. O Eygenios1 το έθεσε σωστά. Εφόσον κάνεις μόνον σύγκριση δεν χρειάζονται μετατροπές. Και σωστά λέει ότι ένα bmp αρχίζει με 'ΒΜ'. Σου ξαναλέω όμως ότι το header μπορεί να έχει μέγεθος 40 bytes κι όχι 14 και να έχει επιπλέον και ένα color table. Η σωστή ανάγνωση είναι απαραίτητη αν επιχειρήσεις και κάτι άλλο διότι τότε χρειάζεσαι πραγματικά την εικόνα. Evgenios το ειδα το Link που εβαλες αλλα ειναι ψoφιο.....( και γενικοτερα διαβασα ολο ποστ οκ! ) Τελικά εχετε δικιο σε αυτο που λέτε καθως δεν εχω σκοπο προς το παρον να επεκταθω οποτε θα φροντισω μεσω pointers των blocks μνημης να τα συγκρινω αλλα δεν εχω ιδεα πως γινεται !!!!! κ παλι HELP
V.I.Smirnov Δημοσ. 31 Μαΐου 2010 Δημοσ. 31 Μαΐου 2010 Τελικά εχετε δικιο σε αυτο που λέτε καθως δεν εχω σκοπο προς το παρον να επεκταθω οποτε θα φροντισω μεσω pointers των blocks μνημης να τα συγκρινω.( καμια ιδεα κ απο εσας... ) γνωριζω και για τα ιστογραμματα αλλα προς το παρον ας μην τα αγγιξω.....καν! Σε ότι αφορά τα bmp ο σωστός χειρισμός τους είναι μάλλον δύσκολος και πολύπλοκος. Για να πάρεις μια ιδέα, δες τις παρακάτω δυο ρουτίνες. Η πρώτη φορτώνει ένα bmp αρχείο από τον δίσκο στη μνήμη και επιστρέφει ένα δείκτη στα pixel bits. Tα pixel bits είναι raw data του bmp (δηλ. της εικόνας) και πρέπει να μετατραπούν σε έναν RGB πίνακα. Αυτό το κάνει η δεύτερη ρουτίνα : μετατρέπει αυτά τα pixel bits σε ένα RGB πίνακα και επιστρέφει ένα δείκτη σ' αυτόν. Αυτό δηλ. που κάνεις κι εσύ με την διαφορά ότι εγώ το κάνω σωστά... Η περίπτωση που εφαρμόζω είναι μόνον για βάθος χρώματος 24 ή 8 bit και χωρίς συμπίεση RLE. Aυτά είναι και τα πιο συνηθισμένα σήμερα. Μια εικόνα που έχει βάθος χρώματος πχ. 16 bit δεν θα μετατραπεί σωστά. Στην δεύτερη ρουτίνα, οι τύποι δεδομένων με το πρόθεμα GL είναι από το openGL όπου την είχα χρησιμοποιήσει κάποτε για να φορτώνω bmp αρχεία ως υφές. Πολύ εύκολα μπορείς να βρεις σε τι αντιστοιχούν στην C/C++. >/* 'LoadDIBitmap()' - Load a DIB/BMP file from disk. (It must be an expanded Windows DIB - see Petzold p.730). Returns a pointer to the DIB pixel bits if successful, NULL otherwise. */ void* LoadDIBitmap(char *filename, BITMAPINFO **pInfo) { FILE *fp; // open file pointer void *bits; // pointer to DIB pixel bits DWORD bitsize, // size of DIB infosize, // size of header information browlength; // length in bytes of each DIB pixels row BITMAPFILEHEADER header; // file header // Try opening the file; use "rb" mode to read this binary file. if ( (fp = fopen(filename, "rb")) == NULL ) return NULL; // Read the file header (BITMAPFILEHEADER structure) // and any following DIB information... if ( fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1 ) { // Couldn't read the file header - return NULL fclose(fp); return NULL; } if (header.bfType != 'MB') // check for BM reversed (0x4D42) { // Not a DIB file - return NULL fclose(fp); return NULL; } // Size of BITMAPINFO header plus the size of color table if exist infosize = header.bfOffBits - sizeof(header); // Take a pointer to a memory block for BITMAPINFO structure and // store it to *pInfo which is a pointer to BITMAPINFO . if ( (*pInfo = (BITMAPINFO *) calloc(1,infosize)) == NULL ) { // Couldn't allocate memory for DIB info - return NULL fclose(fp); return NULL; } // Read from fp file the infosize bytes of size 1 byte and // store them in a buffer pointed by *pInfo which is a pointer to BITMAPINFO if (fread(*pInfo, 1, infosize, fp) < infosize) { // Couldn't read the DIB header - return NULL free(*pInfo); fclose(fp); return NULL; } GLubyte* MakeRGBfromDIB(BITMAPINFO *pInfo, void *bits) { int i, j; DWORD rgb24size, // total size of bitmap browlength; // length in bytes of each bitmap row GLubyte *newbits, // pointer to RGB bits *from, *to; // pointers to scan memory where DIB and RGB images are stored GLubyte colorval, // color value (from DIB color table) r,g,b; // r,g,b colors // Compute the length in bytes of each DIB pixels row // This must be a multiple of 4 - see Petzold p.728 browlength = 4 * ( ( pInfo->bmiHeader.biWidth * pInfo->bmiHeader.biBitCount + 31 ) / 32); // Compute the total size in bytes of the 24 bit RGB bitmap rgb24size = pInfo->bmiHeader.biWidth * pInfo->bmiHeader.biHeight; // Allocate memory for the 24 bit RGB bitmap if ( ( newbits = (GLubyte *) calloc(rgb24size, sizeof(RGBTRIPLE)) ) == NULL ) return NULL; /* * Copy the original DIB pixel bits to the new array, converting as necessary. */ switch (pInfo->bmiHeader.biCompression) { case BI_RGB : // Put code here to handle the cases of biBitCount=1,4,8,16,24,32 // Only the case biBitCount = 24 and 8 are implemented here. if (pInfo->bmiHeader.biBitCount == 24) { // In the 24 bit DIB the order of colors is blue,green,red. // In the new 24 bit RGB image the order of colors must be red,green,blue. for (i = 0; i < pInfo->bmiHeader.biHeight; i++) { from = ((GLubyte *)bits) + i * browlength; to = newbits + i * (pInfo->bmiHeader.biWidth) * sizeof(RGBTRIPLE); for (j = 0; j < pInfo->bmiHeader.biWidth; j++) // Put to the position of memory pointed by newbits // the color bytes of DIB with blue and red in swapped order. { *(to+0) = *(from+2); *(to+1) = *(from+1); *(to+2) = *(from+0); // (this can be written also as to[2] = from[0] and likewise for the other two); from += 3; // increase the position on DIB pixel bits by 3 bytes to += 3; // increase the position on rgb pixel bits by 3 bytes } } } if (pInfo->bmiHeader.biBitCount == 8) { // Remember that an 8 bit DIB has a color table with 256 elements max. for (i = 0; i < pInfo->bmiHeader.biHeight; i++) { from = ((GLubyte *)bits) + i * browlength; to = newbits + i * (pInfo->bmiHeader.biWidth) * sizeof(RGBTRIPLE); for (j = 0; j < pInfo->bmiHeader.biWidth; j++) { // Read the color value of pixel(i,j) i.e. the DIB pixel byte. // This is a value of the color table, not an rgb value. colorval = *from ; // Find the corresponding r,g,b values of this color from color table. r = pInfo->bmiColors[colorval].rgbRed; g = pInfo->bmiColors[colorval].rgbGreen; b = pInfo->bmiColors[colorval].rgbBlue; *(to+0) = r; *(to+1) = g; *(to+2) = b; from += 1; // increase the position on DIB pixel bits by 1 byte to += 3; // increase the position on rgb pixel bits by 3 bytes } } } break; // these remain to be implemented... case BI_RLE4 : case BI_RLE8 : case BI_BITFIELDS : break; } return newbits; } Να ένα παράδειγμα χρήσης τους : φορτώνω ένα bmp και φτιάχνω τον πίνακα με τα χρώματα. > BITMAPINFO *pInfo; // DIB information void *bits; // DIB pixel bits GLubyte *rgb; // bitmap RGB pixels /* * Try loading the DIB and converting it to RGB... */ bits = LoadDIBitmap("EIKONA.bmp", &pInfo); // pInfo is a pointer to BITMAPINFO and we must pass it by reference to change the address which it points if (bits == NULL) return; rgb = MakeRGBfromDIB(pInfo, bits); // make an RGB image from the DIB pixel bits if (rgb == NULL) { free(pInfo); free(bits); return; } Ο rgb είναι ένας δείκτης στον πίνακα με τα χρώματα του bmp. Αυτά μπορείς να τα κάνεις τώρα ότι θέλεις. Να μεταβάλεις την φωτεινότητα, να υπολογίσεις ιστογράμματα, να εντοπίσεις ακμές... Για να φτιάξω τις αυτές τις ρουτίνες είχα διαβάσει από τα δυο βιβλία που σου ανέφερα, κυρίως του Petzold που ανέλυε λεπτομερώς την δομή του header. Φαίνεται και από τα σχόλια. Πολύ λεπτομέρεια. Σε τέτοια πράγματα φαίνεται ποιοί ασχολούνται πραγματικά και ποιοί βαυκαλίζονται ότι είναι προγραμματιστές. Και χωρίς βιβλία δεν γίνεται δουλειά.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.