Εδώ βλέπετε τις διαφορές μεταξύ της επιλεγμένης έκδοσης και της τρέχουσας έκδοσης της σελίδας.
| Προηγούμενος έλεγχος και από τις δύο πλευρές Προηγούμενη αναθεώρηση Επόμενη αναθεώρηση | Προηγούμενη αναθεώρηση | ||
|
opencv [2020/02/23 13:32] John_Crabs Αλλαγή Αντίθεσης και Φωτεινότητας εικόνας |
opencv [2020/11/21 09:52] (τρέχουσα) |
||
|---|---|---|---|
| Γραμμή 5: | Γραμμή 5: | ||
| ====== Εισαγωγή στην OpenCV ====== | ====== Εισαγωγή στην OpenCV ====== | ||
| - | ====Τι είναι η OpenCV==== | + | |
| + | =====Τι είναι η OpenCV===== | ||
| Η OpenCV(Open-source Computer Vision) είναι μία βιβλιοθήκη που περιέχει συναρτήσεις, | Η OpenCV(Open-source Computer Vision) είναι μία βιβλιοθήκη που περιέχει συναρτήσεις, | ||
| Γραμμή 13: | Γραμμή 14: | ||
| - | ====Βασικές εφαρμογές της OpenCV==== | + | |
| + | |||
| + | |||
| + | |||
| + | |||
| + | =====Βασικές εφαρμογές της OpenCV===== | ||
| Όπως και με κάθε άλλη γλώσσα προγραμματισμού, | Όπως και με κάθε άλλη γλώσσα προγραμματισμού, | ||
| Γραμμή 19: | Γραμμή 25: | ||
| Ας ξεκινήσουμε λοιπόν. | Ας ξεκινήσουμε λοιπόν. | ||
| - | ===Αλλαγή Αντίθεσης - Φωτεινότητας Εικόνας=== | + | ====Αλλαγή Αντίθεσης - Φωτεινότητας Εικόνας==== |
| Ο υπολογιστής, | Ο υπολογιστής, | ||
| Γραμμή 63: | Γραμμή 69: | ||
| newImg[y, x, c] = np.clip(contrastVal * img[y, x, c] + brightnessVal, | newImg[y, x, c] = np.clip(contrastVal * img[y, x, c] + brightnessVal, | ||
| | | ||
| - | # newImg = cv.convertScaleAbs(image, alpha=contrastVal, | + | # newImg = cv.convertScaleAbs(img, alpha=contrastVal, |
| | | ||
| if exportFolderPath is not None: # Check if an export path has need set | if exportFolderPath is not None: # Check if an export path has need set | ||
| Γραμμή 92: | Γραμμή 98: | ||
| - Το άνοιγμα της εικόνας πραγματοποιείται με τη συνάρτηση **cv.imread(src, | - Το άνοιγμα της εικόνας πραγματοποιείται με τη συνάρτηση **cv.imread(src, | ||
| - Με ίδια λογική για την εξαγωγή εικόνας χρησιμοποιείται η συνάρτηση **cv.imwrite(filename, | - Με ίδια λογική για την εξαγωγή εικόνας χρησιμοποιείται η συνάρτηση **cv.imwrite(filename, | ||
| - | - Για την επεξεργασία της εικόνας στο παραπάνω παράδειγμα χρησιμοποιήθηκε ένα nested for loop. Στη θέση των for loop, θα μπορούσε να χρησιμοποιηθεί απευθείας η συνάρτηση cv.convertScaleAbs(image, | + | - Για την επεξεργασία της εικόνας στο παραπάνω παράδειγμα χρησιμοποιήθηκε ένα nested for loop. Στη θέση των for loop, θα μπορούσε να χρησιμοποιηθεί απευθείας η συνάρτηση |
| + | |||
| + | |||
| + | ====Φιλτράρισμα Εικόνας==== | ||
| + | |||
| + | Για τη χρήση φίλτρων στην OpenCV χρησιμοποιείται η συνάρτηση cv.filter2D(src, | ||
| + | |||
| + | Παρακάτω παρατίθεται κώδικας για τη χρήση μερικών βασικών φίλτρων. | ||
| + | |||
| + | ===Φίλτρο Δέλτα=== | ||
| + | |||
| + | def deltaFiltering(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False, None | ||
| + | |||
| + | # Set the filter | ||
| + | kernel = np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | |||
| + | print(str(dt.datetime.now()) + " : Image filtering: | ||
| + | print(kernel) | ||
| + | newImg = cv.filter2D(src=img, | ||
| + | |||
| + | if exportFolderPath is not None: # Check if an export path has need set | ||
| + | if exportImageName is None: # Check if user has not specify a name | ||
| + | exportImageName = os.path.splitext(os.path.basename(src))[0] | ||
| + | exportImageName = exportImageName + " | ||
| + | imgTypeFormat = checkImgFileType(src) | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | else: | ||
| + | imgTypeFormat = checkImgFileType(exportImageName) | ||
| + | exportImageName = os.path.splitext(os.path.basename(exportImageName))[0] | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | exportAt = exportFolderPath + exportImageName + imgTypeFormat | ||
| + | print(str(dt.datetime.now()) + " : Write image file at %s" % exportAt) | ||
| + | cv.imwrite(exportAt, | ||
| + | |||
| + | return True, newImg | ||
| + | |||
| + | ===Φίλτρο Παραγώγου=== | ||
| + | |||
| + | def shiftAndSubtractFilter(src: | ||
| + | | ||
| + | | ||
| + | | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False, None | ||
| + | |||
| + | # Set the filter | ||
| + | kernel = np.array(([0, | ||
| + | [0, 0, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if topLeft: | ||
| + | kernel = kernel + np.array(([-1, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if topMiddle: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if topRight: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if centerLeft: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [-1, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if centerMiddle: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if centerRight: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, -1], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | if bottomLeft: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [-1, 0, 0]), np.float32) | ||
| + | if bottomMiddle: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, -1, 0]), np.float32) | ||
| + | if bottomRight: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, 1, 0], | ||
| + | [0, 0, -1]), np.float32) | ||
| + | |||
| + | print(str(dt.datetime.now()) + " : Image filtering: | ||
| + | print(kernel) | ||
| + | newImg = cv.filter2D(src=img, | ||
| + | |||
| + | if exportFolderPath is not None: # Check if an export path has need set | ||
| + | if exportImageName is None: # Check if user has not specify a name | ||
| + | exportImageName = os.path.splitext(os.path.basename(src))[0] | ||
| + | exportImageName = exportImageName + " | ||
| + | imgTypeFormat = checkImgFileType(src) | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | else: | ||
| + | imgTypeFormat = checkImgFileType(exportImageName) | ||
| + | exportImageName = os.path.splitext(os.path.basename(exportImageName))[0] | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | exportAt = exportFolderPath + exportImageName + imgTypeFormat | ||
| + | print(str(dt.datetime.now()) + " : Write image file at %s" % exportAt) | ||
| + | cv.imwrite(exportAt, | ||
| + | |||
| + | return True, newImg | ||
| + | |||
| + | ===Ανίχνευση Ακμών=== | ||
| + | |||
| + | def edgeDetection(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False, None | ||
| + | |||
| + | # Set the filter | ||
| + | kernel = np.array(([1 / 8, 1 / 8, 1 / 8], | ||
| + | [1 / 8, 1, 1 / 8], | ||
| + | [1 / 8, 1 / 8, 1 / 8]), np.float32) | ||
| + | |||
| + | if centerMiddle: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, -1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | |||
| + | print(str(dt.datetime.now()) + " : Image filtering: | ||
| + | print(kernel) | ||
| + | newImg = cv.filter2D(src=img, | ||
| + | |||
| + | if exportFolderPath is not None: # Check if an export path has need set | ||
| + | if exportImageName is None: # Check if user has not specify a name | ||
| + | exportImageName = os.path.splitext(os.path.basename(src))[0] | ||
| + | exportImageName = exportImageName + " | ||
| + | imgTypeFormat = checkImgFileType(src) | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | else: | ||
| + | imgTypeFormat = checkImgFileType(exportImageName) | ||
| + | exportImageName = os.path.splitext(os.path.basename(exportImageName))[0] | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | exportAt = exportFolderPath + exportImageName + imgTypeFormat | ||
| + | print(str(dt.datetime.now()) + " : Write image file at %s" % exportAt) | ||
| + | cv.imwrite(exportAt, | ||
| + | |||
| + | return True, newImg | ||
| + | |||
| + | ===Ενίσχυση Ακμών=== | ||
| + | |||
| + | def edgeEnhancement(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False, None | ||
| + | |||
| + | # Set the filter | ||
| + | if kappa > 8: | ||
| + | kappa = 8 | ||
| + | elif kappa < -8: | ||
| + | kappa = -8 | ||
| + | |||
| + | kernel = np.array(([-kappa / 8, -kappa / 8, -kappa / 8], | ||
| + | | ||
| + | | ||
| + | |||
| + | if centerMiddle: | ||
| + | kernel = kernel + np.array(([0, | ||
| + | [0, -1, 0], | ||
| + | [0, 0, 0]), np.float32) | ||
| + | |||
| + | print(str(dt.datetime.now()) + " : Image filtering: | ||
| + | print(kernel) | ||
| + | newImg = cv.filter2D(src=img, | ||
| + | |||
| + | if exportFolderPath is not None: # Check if an export path has need set | ||
| + | if exportImageName is None: # Check if user has not specify a name | ||
| + | exportImageName = os.path.splitext(os.path.basename(src))[0] | ||
| + | exportImageName = exportImageName + " | ||
| + | imgTypeFormat = checkImgFileType(src) | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | else: | ||
| + | imgTypeFormat = checkImgFileType(exportImageName) | ||
| + | exportImageName = os.path.splitext(os.path.basename(exportImageName))[0] | ||
| + | if imgTypeFormat is None: # If user hasn't specify a type then export image as JPG | ||
| + | imgTypeFormat = " | ||
| + | exportAt = exportFolderPath + exportImageName + imgTypeFormat | ||
| + | print(str(dt.datetime.now()) + " : Write image file at %s" % exportAt) | ||
| + | cv.imwrite(exportAt, | ||
| + | |||
| + | return True, newImg | ||
| + | |||
| + | |||
| + | ====Χρήση της OpenCV για προβολή εικόνας σε GUI==== | ||
| + | |||
| + | Η OpenCV παρέχει τις δικές της εντολές για τη δημιουργία γραφικού περιβάλλοντος. Σε αυτή την ενότητα θα γίνει σύντομη περιγραφή του περιβάλλοντος αυτού. | ||
| + | |||
| + | ===Άνοιγμα Παραθύρου για Προβολή Εικόνας=== | ||
| + | |||
| + | Για τη δημιουργία παραθύρου χρησιμοποιείται η συνάρτηση **cv.namesWindow(winname, | ||
| + | |||
| + | Στη συνέχεια για την προβολή της εικόνας στο παράθυρο χρησιμοποιούνται η συνάρτηση **cv.imshow(winname, | ||
| + | |||
| + | Αφού τερματιστεί με κάποιο τρόπο η προβολή της εικόνας, | ||
| + | |||
| + | def openImageInWindow(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False | ||
| + | |||
| + | windowName = os.path.basename(src) | ||
| + | cv.namedWindow(winname=windowName, | ||
| + | cv.imshow(winname=windowName, | ||
| + | cv.waitKey(0) | ||
| + | cv.destroyAllWindows() | ||
| + | |||
| + | return True | ||
| + | |||
| + | ===Χρήση Πυραμίδων για Προβολή Μεγάλων Εικόνων=== | ||
| + | |||
| + | Όπως αναφέρθηκε παραπάνω όταν μία εικόνα είναι πολύ μεγάλη, | ||
| + | |||
| + | **Προσοχή: | ||
| + | |||
| + | Η για τη δημιουργία πυραμίδα εικόνας χρησιμοποιείται η συνάρτηση cv.pyrDown(src, | ||
| + | |||
| + | def openImageInWindowPyramidVersion(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read image file at %s" % src) | ||
| + | img = cv.imread(src) | ||
| + | |||
| + | # Check if image was opened correctly | ||
| + | if img is None: | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False | ||
| + | |||
| + | h, w, _channels = map(int, img.shape) | ||
| + | while w > 1024 or h > 720: # We want the image to fit the screen (this values ensures that) | ||
| + | img = cv.pyrDown(src=img, | ||
| + | # (there is also cv.pyrUp(src=img, | ||
| + | h, w, _channels = map(int, img.shape) | ||
| + | print(" | ||
| + | |||
| + | windowName = os.path.basename(src) | ||
| + | cv.namedWindow(winname=windowName, | ||
| + | cv.imshow(winname=windowName, | ||
| + | cv.waitKey(0) | ||
| + | cv.destroyAllWindows() | ||
| + | |||
| + | return True | ||
| + | |||
| + | ===Προβολή Βίντεο=== | ||
| + | |||
| + | Με αντίστοιχο γίνεται και η προβολή ενός βίντεο. Το βίντεο αποτελείται από μία σειρά εικόνων που η μία διαδέχεται την άλλη με κάποια συγκεκριμένη ταχύτητα που μετριέται σε καρέ/ | ||
| + | |||
| + | Για το άνοιγμα ενός βίντεο η OpenCV έχει δημιουργήσει τη συνάρτηση **cv.VideoCapture(src)**, | ||
| + | Αυτό στην πράξη μεταφράζεται ως **success, frame = videoFile.read()**. Η συνάρτηση **read()** επιστρέφει σαν πρώτη παράμετρο την επιτυχία ή αποτυχία ανάγνωσης του καρέ (για αυτό και θα πρέπει να γίνεται πάντα έλεγχος εάν διαβάστηκε το καρέ ή όχι) και σαν δέυτερη παράμετρο επιστροφής είναι το καρέ. Εάν δεν γίνει έλεγχος, | ||
| + | |||
| + | ==Απλή Προσπέλαση-Προβολή Βίντεο== | ||
| + | |||
| + | def openVideoInWindow(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read video file at %s" % src) | ||
| + | videoFile = cv.VideoCapture(src) | ||
| + | |||
| + | # Check if video was opened correctly | ||
| + | if not videoFile.isOpened(): | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False | ||
| + | |||
| + | windowName = os.path.basename(src) | ||
| + | cv.namedWindow(winname=windowName, | ||
| + | |||
| + | videoPlay = True | ||
| + | while videoPlay: | ||
| + | success, frame = np.array(videoFile.read()) | ||
| + | if not success: | ||
| + | break | ||
| + | cv.imshow(winname=windowName, | ||
| + | press_ESC = cv.waitKey(33) | ||
| + | if press_ESC is 27: | ||
| + | break | ||
| + | cv.destroyAllWindows() | ||
| + | |||
| + | |||
| + | ==Προβολή Βίντεο Με Χρήση Πυραμίδων== | ||
| + | |||
| + | Εάν η ανάλυση του βίντεο είναι πολύ μεγάλη, | ||
| + | λόγο συνιστάται η χρήση πυραμίδων για μείωση της ανάλυσης στα επιθυμητά όρια. | ||
| + | |||
| + | def openVideoInWindowPyramidVersion(src: | ||
| + | print(" | ||
| + | print(str(dt.datetime.now()) + " : Read video file at %s" % src) | ||
| + | videoFile = cv.VideoCapture(src) | ||
| + | |||
| + | # Check if video was opened correctly | ||
| + | if not videoFile.isOpened(): | ||
| + | print(str(dt.datetime.now()) + " | ||
| + | return False | ||
| + | |||
| + | windowName = os.path.basename(src) | ||
| + | cv.namedWindow(winname=windowName, | ||
| + | |||
| + | videoPlay = True | ||
| + | while videoPlay: | ||
| + | success, frame = videoFile.read() | ||
| + | if not success: | ||
| + | break | ||
| + | |||
| + | h, w, _channels = map(int, frame.shape) | ||
| + | while w > 1024 or h > 720: # We want the image to fit the screen (this values ensures that) | ||
| + | frame = cv.pyrDown(src=frame, | ||
| + | # (there is also cv.pyrUp(src=img, | ||
| + | h, w, _channels = map(int, frame.shape) | ||
| + | |||
| + | cv.imshow(winname=windowName, | ||
| + | press_ESC = cv.waitKey(33) | ||
| + | if press_ESC is 27: | ||
| + | break | ||
| + | cv.destroyAllWindows() | ||