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

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

Δημοσ. (επεξεργασμένο)

Καλημέρα σας παιδιά,

 

επειδή μου αρέσουν πολύ οι ερωτήσεις που έχουν έναν απώτερο εκπαιδευτικό σκοπό (γι'αυτό και ο γενικός τίτλος) ξεκινάω:

 

Σε ένα project φτιάξαμε 3 εκτελέσιμα (σε C++, δεν έχει σημασία) και θέλουμε να τα ενώσουμε με ένα bash script (θα μπορούσε να είναι python, αλλά επειδή μιλάμε για embedded system ας μείνουμε σε αυτά που μας παρέχει ένα GNU/Linux).

 

Το script που έχουμε γράψει είναι το παρακάτω και κάνει τη δουλειά που θέλουμε, αλλά θα το εκτιμούσα αν άκουγα κάποιες συμβουλές για μία "πιο σωστή" συγγραφή (δεν έχω ασχοληθεί γενικά με bash scripting):

#!/bin/sh

EXPECTED_ARGS=1
E_BADARGS=1

if [ $# -ne $EXPECTED_ARGS ]
then
    echo "Usage: ./lpr <input.img>"
    exit $E_BADARGS
fi

rm -f output.txt
./1_text_isolation/txtiso.out $1 > /dev/null 2>&1
./2_character_segmentation/charsegm.out final.png > /dev/null 2>&1
for i in ` ls | grep letter `;
do
    ./3_ocr/ocr.out $i | grep '[Α-Ωα-ω0-9]' | perl -p -e 's/[^Α-Ω0-9]+//' | tr '\n' '\0' >> output.txt
done

rm final.png
for i in ` ls | grep letter `;
do
    rm $i
done

Το πρώτο πρόγραμμα παίρνει σαν όρισμα ένα αρχείο εικόνας και βγάζει μία εικόνα σαν output, την final.png, την οποία δέχεται σαν όρισμα το δεύτερο εκτελέσιμο. Το δεύτερο εκτελέσιμο με τη σειρά του, σπάει τα γράμματα από την εικόνα εισόδου και δημιουργεί μία εικόνα για κάθε γράμμα με ονομασία letterXX.png. Από εκεί και πέρα θέλω να εφαρμόσω OCR πάνω σε κάθε γράμμα ξεχωριστά. Αλλά επειδή το output μιας κλήσης στο τρίτο εκτελέσιμο παράγει κι extra πληροφορία, θα ήθελα με κάποιο τρόπο να εξάγω ότι θέλω από το script, χωρίς να πειράξω το πηγαίο κώδικα.

 

Πχ, αυτό..

OCR output:
Ε
OCR output:
Β]
OCR output:
Κ
OCR output:
5
OCR output:
2
OCR output:
2
OCR output:
'7

θέλω να γίνει έτσι:

ΕΒΚ5227

Γνωρίζω τί κάνει αυτό που έγραψα στο script, αλλά είμαι σίγουρος πως υπάρχει μία καλύτερη λύση.

 

Επίσης έχω και μία βασική απορία:

 

Όταν πάω να αντικαταστήσω αυτό το κομμάτι κώδικα:

perl -p -e 's/[^Α-Ω0-9]+//' | tr '\n' '\0'

με αυτό:

perl -p -e 's/([^Α-Ω0-9]|[\n])+//'

δε μου δουλεύει. Δε μπορώ να καταλάβω γιατί.

Επεξ/σία από gon1332
Δημοσ.

 

for i in ` ls | grep letter `;
Το δεύτερο εκτελέσιμο με τη σειρά του, σπάει τα γράμματα από την εικόνα εισόδου και δημιουργεί μία εικόνα για κάθε γράμμα με ονομασία letterXX.png.

 

Το πρώτο που μου βάρεσε άσχημα είναι αυτό. Αν ψάξεις για περιττές εκφράσεις σε shell αυτό είναι συνήθως δεύτερο στο top10 μετά την cat.

 

1) Ενδέχεται να σου δημιουργήσει προβλήματα αν αύριο αλλάξει η ls και συμπεριλάβει στην έξοδό της κάτι με την λέξη letter (στην παρούσα περίπτωση με την ls πολύ δύσκολο αλλά υπάρχουν περιπτώσεις με άλλες εντολές που μπορείς να την πατήσεις).

 

2) Πρακτικά δεν θα φανεί ούτε σε embedded πλέον αλλά εισάγει τρομερό (θεωρητικά) overhead χωρίς κανένα λόγο. Τα backquotes θα τρέξουν ένα subshell, θα γίνουν redirections για stdout, κτλ, θα εκτελεστεί η εξωτερική εντολή ls, θα εκτελεστεί η σχετικά βαριά εντολή grep και θα σου επιστρέψει το αποτέλεσμα.

 

Εφόσον αυτό που θέλεις είναι ένα απλό globbing, γιατί να μην τρέξεις

for i in letter*.png; (ή *letter* ή ό,τι σε βολεύει)
που είναι πιο εύκολο, πιο όμορφο, πιο γρήγορο και δεν μπορεί να σε οδηγήσει σε περιπέτειες ?

 

 

 

    ./3_ocr/ocr.out $i | grep '[Α-Ωα-ω0-9]' | perl -p -e 's/[^Α-Ω0-9]+//' | tr '\n' '\0' >> output.txt
Πχ, αυτό..

OCR output:
Ε
OCR output:
B]
OCR output:
K
OCR output:
5
OCR output:
2
OCR output:
2
OCR output:
'7
θέλω να γίνει έτσι:

ΕΒΚ5227

 

Η εντολή που έδωσες κάνει grep μόνο για ελληνικά αλλά τα Β, Κ σε αυτό που έδωσες, όταν τα έκανα copy-paste μου εμφανίζονται αγγλικά. Είναι όντως αγγλικά ?

  • Like 1
Δημοσ.

Η εντολή που έδωσες κάνει grep μόνο για ελληνικά αλλά τα Β, Κ σε αυτό που έδωσες, όταν τα έκανα copy-paste μου εμφανίζονται αγγλικά. Είναι όντως αγγλικά ?

Είναι ελληνικά. Απλά αντέγραψα το output με το χέρι και μάλλον μπέρδεψα τις γλώσσες. Το άλλαξα στο αρχικό μου post.

Δημοσ.

Είναι ελληνικά. Απλά αντέγραψα το output με το χέρι και μάλλον μπέρδεψα τις γλώσσες. Το άλλαξα στο αρχικό μου post.

Ωραία τότε :)

 

Όταν πάω να αντικαταστήσω αυτό το κομμάτι κώδικα:

perl -p -e 's/[^Α-Ω0-9]+//' | tr '\n' '\0'
με αυτό:

perl -p -e 's/([^Α-Ω0-9]|[\n])+//'
δε μου δουλεύει. Δε μπορώ να καταλάβω γιατί.

 

Πρόσθεσε τον modifier g στο τέλος και θα παίξει. Μια πιο απλή μορφή με το ίδιο αποτέλεσμα είναι 's/[^Α-Ω0-9]+|\n//g'. Τώρα που το σκέφτομαι καλύτερα, και το σκέτο s/[^Α-Ω0-9]+//g' θα πρέπει να παίξει αφού οι newlines δεν είναι μέσα στο set.

Δημοσ.

Ωραία τότε :)

 

 

Πρόσθεσε τον modifier g στο τέλος και θα παίξει. Μια πιο απλή μορφή με το ίδιο αποτέλεσμα είναι 's/[^Α-Ω0-9]+|\n//g'. Τώρα που το σκέφτομαι καλύτερα, και το σκέτο s/[^Α-Ω0-9]+//g' θα πρέπει να παίξει αφού οι newlines δεν είναι μέσα στο set.

Ohh... ωραία! g για global ανάλογο του Vim όταν θέλει κανείς να κάνει αντικατάσταση.

 

Τέλεια, ευχαριστώ.

 

Είχα πάει να χρησιμοποιήσω sed στην αρχή, αλλά σε αυτά που βρήκα δεν κατάλαβα και πολλά.

 

Γενικότερα, οποιαδήποτε άλλη παρατήρηση θα ήταν πολύ χρήσιμη.

Δημοσ.

Προφανώς. :P

 

Νομίζω ότι το κεφάλι μου έγινε κυμάς.

:)

 

Οπότε για την ευκολία όποιου θέλει να προτείνει κάτι, για την ώρα έχουμε:

 

#!/bin/sh

EXPECTED_ARGS=1
E_BADARGS=1

if [ $# -ne $EXPECTED_ARGS ]
then
    echo "Usage: $0 <input.img>"
    exit $E_BADARGS
fi
rm -f output.txt

./1_text_isolation/txtiso.out $1 > /dev/null 2>&1

./2_character_segmentation/charsegm.out final.png > /dev/null 2>&1
rm final.png

for i in letter*.png;
do
    ./3_ocr/ocr.out $i | grep '[Α-Ωα-ω0-9]' | perl -p -e 's/[^Α-Ω0-9]+//g' >> output.txt
    rm $i    
done
Εκτός από όσα έχουμε συζητήσει, πήγα το "rm final.png" λίγο πιο πριν, αφού το χρησιμοποιήσει το 2_κτλ και παράξει τα letterXY.png και επίσης άλλαξα το hardcoded "./lpr" σε $0.
  • Like 1
Δημοσ.

:)

 

Οπότε για την ευκολία όποιου θέλει να προτείνει κάτι, για την ώρα έχουμε:

...

 

Υπάρχει περίπτωση να απαντήσεις σε κάποιο θέμα και να προτείνει κάποιος κάτι καλύτερο? :P :X

  • Like 1
Δημοσ.

:)

 

Οπότε για την ευκολία όποιου θέλει να προτείνει κάτι, για την ώρα έχουμε:

 

 

#!/bin/sh

EXPECTED_ARGS=1
E_BADARGS=1

if [ $# -ne $EXPECTED_ARGS ]
then
    echo "Usage: $0 <input.img>"
    exit $E_BADARGS
fi
rm -f output.txt

./1_text_isolation/txtiso.out $1 > /dev/null 2>&1

./2_character_segmentation/charsegm.out final.png > /dev/null 2>&1
rm final.png

for i in letter*.png;
do
    ./3_ocr/ocr.out $i | grep '[Α-Ωα-ω0-9]' | perl -p -e 's/[^Α-Ω0-9]+//g' >> output.txt
    rm $i    
done

 

 

Εκτός από όσα έχουμε συζητήσει, πήγα το "rm final.png" λίγο πιο πριν, αφού το χρησιμοποιήσει το 2_κτλ και παράξει τα letterXY.png και επίσης άλλαξα το hardcoded "./lpr" σε $0.

Μια χαρά! Κι εγώ κάπως έτσι κατέληξα με αυτά που πρότεινες.

 

Ευχαριστώ πολύ! :)

Δημοσ.

Υπάρχει περίπτωση να απαντήσεις σε κάποιο θέμα και να προτείνει κάποιος κάτι καλύτερο? :P :X

Μπορεί να διαβάζει το φόρουμ ο chuck norris :P

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...