Paytor Δημοσ. 7 Οκτωβρίου 2006 Δημοσ. 7 Οκτωβρίου 2006 Καλησπέρα!!! Κάνω ενα πρόγραμμα σύγκρισης εικόνων.Υπάρχει κανένας τρόπος να υπολογίζω τις τιμές των pixel(0-255) μιας grayscale εικόνας? Μέχρι στιγμής εχω δοκιμάσει να πάρω τις τιμές με την χρήση τις ιδιότητας Point(i, j) του picturebox.Τις τιμές τις αποθηκεύω σε εναν πίνακα (array) και μετά τις τυπώνω σε άνα αρχείο. Η τιμή που παίρνω ειναι όμως πολύ μεγάλη π.χ 12961221 για το πρώτο pixel.Τι αντιπροσωπέυει αυτη η τιμή ακριβώς? Επίσης εχω προσθέσει εναν κώδικα που υπολογίζει κάθε τιμή RGB red green και blue αλλά δουλέυει μόνο για το πρώτο pixel και μετά βγάζει την ίδια τιμή για όλα τα υπόλοιπα.Ο κώδικας ειναι ο παρακάτω: Picture1.ScaleMode = vbPixels ReDim Values(0 To Picture1.ScaleWidth, 0 To Picture1.ScaleHeight) As Long Dim i, j As Integer For i = 0 To Picture1.ScaleWidth - 1 For j = 0 To Picture1.ScaleHeight - 1 Values(i, j) = Picture1.Point(i, j) colRed = (Values(i, j) And &HFF&) colGreen = (Values(i, j) And &HFF00&) / &H100 colBlue = (Values(i, j) And &HFF0000) / &H10000 Next j Next i Μετά το τυπώνω σε αρχείο αφου το δηλώσω και το δημιουργήσω ως εξής: For i = 0 To Picture1.ScaleWidth - 1 For j = 0 To Picture1.ScaleHeight - 1 Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _ & j & " " & i & " " & "colRed" & " " & colRed & " " & "colGreen" _ & " " & colGreen & " " & "colBlue" & " " & colBlue) Next j Next i Οποιαδήποτε ιδέα για να λύσω τα προβλήματα που ανέφερα παραπάνω είναι καλοδεχούμενη(ιδιαίτερα για τις τιμες grayscale).
alkisg Δημοσ. 8 Οκτωβρίου 2006 Δημοσ. 8 Οκτωβρίου 2006 12961221 = &HC5C5C5 Δηλαδή Red = C5, Green = C5, Blue = C5. Σου αρκεί ένα οποιοδήποτε από αυτά τα C5, έτσι μπορείς να το πάρεις π.χ. με 12961221 mod 256 όπου mod το υπόλοιπο, δε θυμάμαι πως είναι στη basic. Υ.Γ. κι αν δεν είναι grayscale η εικόνα, πάλι μπορείς να πάρεις το Luminance (0-255) με τον τύπο Y = 0.299 * R + 0.587 * G + 0.114 * B Π.χ. δες http://en.wikipedia.org/wiki/YUV
Leite33 Δημοσ. 8 Οκτωβρίου 2006 Δημοσ. 8 Οκτωβρίου 2006 Σωστά, αλλά στο στο παρακατω παραδειγμα το &Η τι ειναί; Γιατί το αφήνεις απεξώ; 12961221 = &HC5C5C5
alkisg Δημοσ. 8 Οκτωβρίου 2006 Δημοσ. 8 Οκτωβρίου 2006 &H είναι ο συμβολισμός για δεκαεξαδικά νούμερα στη basic. 0x στη C, $ στην Pascal κτλ.
Paytor Δημοσ. 8 Οκτωβρίου 2006 Μέλος Δημοσ. 8 Οκτωβρίου 2006 Ο παρακάτω κώδικας τι κάνει ακριβώς (γραμμη γραμμη).Ξέρω οτι εξάγει τις RGB(red green blue) τιμές για κάθε pixel αλλα θα ήθελα να ξέρω με λεπτομέρειες.Αν μπορει να βοηθήσει κανείς! colRed = Values(i, j) And &HFF colGreen = (Values(i, j) \ &H100) And &HFF colBlue = Values(i, j) \ &H10000 οπου Values(i, j) εχω αναφέρει παραπάνω τι είναι. Ευχαριστώ!!!!
alkisg Δημοσ. 8 Οκτωβρίου 2006 Δημοσ. 8 Οκτωβρίου 2006 Το \ είναι η ακέραια διαίρεση στη Basic. Τα Values σου έχουν τη μορφή &H00BBGGRR, όπου RR = η τιμή του Red (0-255) GG = η τιμή του Green (0-255) BB = η τιμή του Blue (0-255) Επομένως: Values(i, j) And &HFF: παίρνει μόνο τα RR (Values(i, j) \ &H100): διαιρεί το Value και έτσι μένει μόνο το &H0000BBGG. Μετά κάνει And &HFF και μένει μόνο το GG. (Values(i, j) \ &H10000): διαιρεί το Value και έτσι μένει μόνο το &H000000BB. edit: όταν κάνουμε διαίρεση με το &H100, είναι σαν να κυλάμε τον αριθμό δύο δεκαεξαδικά ψηφία προς τα δεξιά. Επίσης, όταν κάνουμε And με το &HFF, κρατάμε μόνο τα τελευταία δύο ψηφία.
Paytor Δημοσ. 8 Οκτωβρίου 2006 Μέλος Δημοσ. 8 Οκτωβρίου 2006 Ευχαριστώ alkisg!Πήρα μια καλή ιδέα του τι γίνεται αναλυτικά στον κώδικα(ολίσθηση ψηφίων), αλλα ακόμα εχω απορία για το τι ακριβώς 'είναι' τα &H100και And &HFF.Το &Η ειναι συμβολισμός για δεκαεξαδικά νούμερα οπως είπες και παραπάνω.Ολο μαζι δηλαδή το &Η100 είναι ο τρόπος που χρησιμοποιούμε για να διαιρέσουμε τον δεκαεξαδικό αριθμό που έχουμε απο κάθε pixel.Διορθωσέ με αν είμαι λάθος.Το And &HFF τι είναι ακριβώς?Το FF εναι το 255 στο δεκαεξαδικό σύστημα?Αυτες είναι οι απορίες που μου απομένουν. Ευχαριστώ!!!
alkisg Δημοσ. 9 Οκτωβρίου 2006 Δημοσ. 9 Οκτωβρίου 2006 Για να καταλάβεις δεκαεξαδικό σύστημα, πρέπει πρώτα να καταλάβεις δυαδικό σύστημα. Λεπτομέρειες στο http://en.wikipedia.org/wiki/Binary_numeral_system Εν ολίγοις: &H000000FF = 255 = 00000000 00000000 00000000 11111111 στο δυαδικό. Βάζω 32 δυαδικά ψηφία γιατί το Values σου έχει 32 bit. Ας πούμε ότι ένα από τα Values σου είναι το 00000000 01010101 10101010 01101100. Όταν κάνεις AND τα δύο παρακάτω, 00000000 00000000 00000000 11111111 00000000 01010101 10101010 01101100 στο αποτέλεσμα υπάρχουν άσσοι μόνο στις θέσεις που και τα δύο είναι άσσοι: 00000000 00000000 00000000 01101100 Δηλαδή, έμεινε μόνο το δεξιά byte, που είναι και το byte της συνιστώσας του χρώματος (R, G, που μας ενδιαφέρει. Με μια πρόταση, το AND κάνει απομόνωση bytes (ή γενικότερα bits).
Paytor Δημοσ. 11 Οκτωβρίου 2006 Μέλος Δημοσ. 11 Οκτωβρίου 2006 Καλημέρα!! Κατάλαβα ακριβώς τι γίνεται στις 3 γραμμές κώδικα που αναλύσαμε παραπάνω.Ευχαριστώ alkisg. Τώρα μια άλλη ερώτηση. Υπάρχει κανένας σύντομος τρόπος να υπολογίσω τις τιμές κάθε πίξελ μίας grayscale(8 bit for each pixel) εικόνας που ειναι αποθηκευμένη πχ στα εγγραφά μου χωρίς να την φορτώσω σε picturebox(Picture.Point)? Μέχρι στιγμής το έχω καταφέρει με τον ίδιο τρόπο που παίρνω τιμές απο έγχρωμη εικόνα.Αυτο που παρατήρησα είναι οτι οι τιμές red green και blue για κάθε πίξελ είναι ίδιες οπότε και με ενδιαφέρει μονο η μια πχ pixel 0,0 red 197 green 197 και blue 197. Τώρα πρέπει να αποθηκέυω τις τιμές σε έναν άλλο πίνακα και μετά να υπολογίσω αρχίζοντας απο το κέντρο του πίνακα(που εχω περάσει τις τιμές) και κυκλικά, δεξιόστροφα η αριστερόστροφα, τις τιμές fourier για τα πίξελ που διατρέχω. Υπάρχει καμία ιδέα ετσι για αρχή πάνω σε αυτό το θέμα??? Ευχαριστώ!!
alkisg Δημοσ. 11 Οκτωβρίου 2006 Δημοσ. 11 Οκτωβρίου 2006 VB δεν ξέρω, αν ήταν Delphi ή C ή Windows API θα σου απαντούσα ότι γίνεται με memory bitmaps... Θα πρέπει να περιμένεις κάποιον σχετικό σε VB....
Paytor Δημοσ. 11 Οκτωβρίου 2006 Μέλος Δημοσ. 11 Οκτωβρίου 2006 Σορι για τον βομβαρδισμό ερωτήσεων αλλα είμαι σχετικά καινούργιος στην Visual Basic.Διάβασα οτι για να συγκρίνεις πίνακες είναι καλύτερο να είναι μιας διάστασης. Πώς μπορεί να γίνει αυτο στην Visual Basic 6?Π.χ για τον κώδικα που έκανα "post" στην αρχή του topic.Μπορεί να βοηθήσει κανένας?Το προβλημά μου ειναι πως θα διαχειριστώ και την ιδιότητα Point(i, j) για μονοδάστατο πίνακα!!! Ευχαριστώ.
alkisg Δημοσ. 11 Οκτωβρίου 2006 Δημοσ. 11 Οκτωβρίου 2006 Έστω δισδιάστατος πίνακας A[N, N] και μονοδιάστατος B[N*N] Το A[i, j] αντιστοιχεί με το στοιχείο B[N*i + j] Οπότε οι μονοδιάστατοι και οι πολυδιάστατοι πίνακες είναι ισοδύναμοι, αρκεί να χρησιμοποιείς τον παραπάνω τύπο...
Paytor Δημοσ. 12 Οκτωβρίου 2006 Μέλος Δημοσ. 12 Οκτωβρίου 2006 Αν τον πίνακα τον δηλώσω έτσι είναι σωστό. Dim Values () As Long(Στα genaral declarations) και μετά να τον κάνω resize ετσι ReDim Values(0 To (Picture1.ScaleWidth + 1) * (Picture1.ScaleHeight + 1) - 1) As Long αλλα το πρόβλημα είναι στον κώδικα παρακάτω αν τον αφήσω όπως έχει νου βγάζει μήνυμα subscribt out of range και αν αλλάξω σε όλες τις γραμμές που υπάρχει το Values(i, j) σε Values(i * j + 1) σεν βγάζει σφάλμα αλλα οι τιμές δεν είναι σωστές.Μερικές σωστές και μερικές λάθος Κώδικας Picture1.ScaleMode = vbPixels ReDim Values(0 To (Picture1.ScaleWidth + 1) * (Picture1.ScaleHeight + 1) - 1) As Long Dim i, j, Y As Integer Dim IntFileNum As Integer IntFileNum = FreeFile Open "C:\\Image Values.txt" For Output As #IntFileNum Print #IntFileNum, "Image Values For Each Pixel Are" For i = 0 To Picture1.ScaleWidth - 1 For j = 0 To Picture1.ScaleHeight - 1 Values(i, j) = Picture1.Point(i, j) grayValue = Values(i, j) And &HFF Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _ & j & " " & i & " " & "grayValue" & " " & grayValue) Next j Next i Close #IntFileNum MsgBox "Done" Καμία βοήθεια????Ευχαριστώ!!!
The_Edge Δημοσ. 12 Οκτωβρίου 2006 Δημοσ. 12 Οκτωβρίου 2006 ReDim Values(0 To (Picture1.ScaleWidth + 1) * (Picture1.ScaleHeight + 1) - 1) As Long Εδώ είναι το πρόβλημα σου, τον ορίζεις ως μονοδιάστατο, ενώ θέλεις να έχεις 2 διαστάσεις. ReDim Values(0 To (Picture1.ScaleWidth - 1), 0 Το (Picture1.ScaleHeight - 1) ) As Long Edit: Μόλις τώρα πρόσεξα ότι θέλεις να το κάνεις με 1 διάσταση. Αν είναι όντως έτσι, αφήνεις τον ορισμό όπως τον είχες και αλλάζεις τις αναφορές που έχεις στο Values(i,j) σύμφωνα με τον τύπο του alkisg.
alkisg Δημοσ. 12 Οκτωβρίου 2006 Δημοσ. 12 Οκτωβρίου 2006 και αν αλλάξω σε όλες τις γραμμές που υπάρχει το Values(i, j) σε Values(i * j + 1) Όχι Values(i * j + 1), βάλε Values(N * j + i), όπου Ν = Picture1.ScaleWidth (ή Values(N * i + j) με N = Picture1.ScaleHeight, ανάλογα με το ποιες ορίζεις στήλες και ποιες γραμμές)
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.