Προς το περιεχόμενο

Grayscale Visual Basic 6


Paytor

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα!!!

Κάνω ενα πρόγραμμα σύγκρισης εικόνων.Υπάρχει κανένας τρόπος να υπολογίζω τις τιμές των 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).

Δημοσ.

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

Δημοσ.

Ο παρακάτω κώδικας τι κάνει ακριβώς (γραμμη γραμμη).Ξέρω οτι εξάγει τις 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) εχω αναφέρει παραπάνω τι είναι.

Ευχαριστώ!!!!

Δημοσ.

Το \ είναι η ακέραια διαίρεση στη 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, κρατάμε μόνο τα τελευταία δύο ψηφία.

Δημοσ.

Ευχαριστώ alkisg!Πήρα μια καλή ιδέα του τι γίνεται αναλυτικά στον κώδικα(ολίσθηση ψηφίων), αλλα ακόμα εχω απορία για το τι ακριβώς 'είναι' τα &H100και And &HFF.Το &Η ειναι συμβολισμός για δεκαεξαδικά νούμερα οπως είπες και παραπάνω.Ολο μαζι δηλαδή το &Η100 είναι ο τρόπος που χρησιμοποιούμε για να διαιρέσουμε τον δεκαεξαδικό αριθμό που έχουμε απο κάθε pixel.Διορθωσέ με αν είμαι λάθος.Το And &HFF τι είναι ακριβώς?Το FF εναι το 255 στο δεκαεξαδικό σύστημα?Αυτες είναι οι απορίες που μου απομένουν.

Ευχαριστώ!!!

Δημοσ.

Για να καταλάβεις δεκαεξαδικό σύστημα, πρέπει πρώτα να καταλάβεις δυαδικό σύστημα.

Λεπτομέρειες στο 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, B) που μας ενδιαφέρει.

 

Με μια πρόταση, το AND κάνει απομόνωση bytes (ή γενικότερα bits).

Δημοσ.

Καλημέρα!!

Κατάλαβα ακριβώς τι γίνεται στις 3 γραμμές κώδικα που αναλύσαμε παραπάνω.Ευχαριστώ alkisg.

Τώρα μια άλλη ερώτηση.

Υπάρχει κανένας σύντομος τρόπος να υπολογίσω τις τιμές κάθε πίξελ μίας grayscale(8 bit for each pixel) εικόνας που ειναι αποθηκευμένη πχ στα εγγραφά μου χωρίς να την φορτώσω σε picturebox(Picture.Point)?

Μέχρι στιγμής το έχω καταφέρει με τον ίδιο τρόπο που παίρνω τιμές απο έγχρωμη εικόνα.Αυτο που παρατήρησα είναι οτι οι τιμές red green και blue για κάθε πίξελ είναι ίδιες οπότε και με ενδιαφέρει μονο η μια πχ pixel 0,0 red 197 green 197 και blue 197.

Τώρα πρέπει να αποθηκέυω τις τιμές σε έναν άλλο πίνακα και μετά να υπολογίσω αρχίζοντας απο το κέντρο του πίνακα(που εχω περάσει τις τιμές) και κυκλικά, δεξιόστροφα η αριστερόστροφα, τις τιμές fourier για τα πίξελ που διατρέχω.

Υπάρχει καμία ιδέα ετσι για αρχή πάνω σε αυτό το θέμα???

Ευχαριστώ!!

Δημοσ.

VB δεν ξέρω, αν ήταν Delphi ή C ή Windows API θα σου απαντούσα ότι γίνεται με memory bitmaps...

 

Θα πρέπει να περιμένεις κάποιον σχετικό σε VB....

Δημοσ.

Σορι για τον βομβαρδισμό ερωτήσεων αλλα είμαι σχετικά καινούργιος στην Visual Basic.Διάβασα οτι για να συγκρίνεις πίνακες είναι καλύτερο να είναι μιας διάστασης.

Πώς μπορεί να γίνει αυτο στην Visual Basic 6?Π.χ για τον κώδικα που έκανα "post" στην αρχή του topic.Μπορεί να βοηθήσει κανένας?Το προβλημά μου ειναι πως θα διαχειριστώ και την ιδιότητα Point(i, j) για μονοδάστατο πίνακα!!!

Ευχαριστώ.

Δημοσ.

Έστω δισδιάστατος πίνακας A[N, N]

και μονοδιάστατος B[N*N]

Το A[i, j] αντιστοιχεί με το στοιχείο B[N*i + j]

 

Οπότε οι μονοδιάστατοι και οι πολυδιάστατοι πίνακες είναι ισοδύναμοι, αρκεί να χρησιμοποιείς τον παραπάνω τύπο...

Δημοσ.

Αν τον πίνακα τον δηλώσω έτσι είναι σωστό.

 

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"

Καμία βοήθεια????Ευχαριστώ!!!

Δημοσ.

 

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.

Δημοσ.
και αν αλλάξω σε όλες τις γραμμές που υπάρχει το Values(i, j) σε Values(i * j + 1)

 

Όχι Values(i * j + 1), βάλε Values(N * j + i), όπου Ν = Picture1.ScaleWidth (ή Values(N * i + j) με N = Picture1.ScaleHeight, ανάλογα με το ποιες ορίζεις στήλες και ποιες γραμμές)

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...