Dear community,
with your great support I coded a perceptual-hash-hanger-finder for digitized super8-films.
I got the hangerfinder working in pycharm.
I created an exe with pyinstaller - but outside of pycharm a new pyqt window is opened again and again.
I guess that I have to hide the hangerfinder behind:
if __name__ == "__main__":
to avoid this Behave.
I'm trying to achieve the following:
When the button "button_HF_Start" is clicked, it is checked, if a film, which is to be checked for hangers, is marked with x in excel.
If the film was marked, the hangerfinder starts examining the frames in folder and when this is done, the timestamps are written to excel.
Then the script ends.
Now I'm a bit confused, because I'm not sure how I have to rearrange my script.
I have a big request (and know it takes a lot of effort):
Could you please show me how I have to rearrange my code?
That would be great, because it was much work for you and me and this is the final step (rearrange the script and creating an exe).
Thanks a lot for your help!! I will be very thankful.
this works in pycharm:
with your great support I coded a perceptual-hash-hanger-finder for digitized super8-films.
I got the hangerfinder working in pycharm.
I created an exe with pyinstaller - but outside of pycharm a new pyqt window is opened again and again.
I guess that I have to hide the hangerfinder behind:
if __name__ == "__main__":
to avoid this Behave.
I'm trying to achieve the following:
When the button "button_HF_Start" is clicked, it is checked, if a film, which is to be checked for hangers, is marked with x in excel.
If the film was marked, the hangerfinder starts examining the frames in folder and when this is done, the timestamps are written to excel.
Then the script ends.
Now I'm a bit confused, because I'm not sure how I have to rearrange my script.
I have a big request (and know it takes a lot of effort):
Could you please show me how I have to rearrange my code?
That would be great, because it was much work for you and me and this is the final step (rearrange the script and creating an exe).
Thanks a lot for your help!! I will be very thankful.
this works in pycharm:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox,QHBoxLayout, QVBoxLayout, QLineEdit, QLabel from PyQt5.QtCore import QCoreApplication import ctypes import os, sys import time import openpyxl from itertools import zip_longest from multiprocessing import Pool from PIL import Image import imagehash p = "C:/hangerfinder/bild_analyse/" def create_phash(frame): # load frames frame = Image. open (p + str (frame)) # create pHash # Compare hashes to determine whether the frames are the same or not phash = str (imagehash.phash(frame)) return phash def difference_count(a: str , b: str ) - > int : # count differences between a and b return sum ( 1 for a, b in zip_longest(a, b) if a ! = b) def phash_iter(d): # frame phash iterator # use multiprocessing to hash frames in parallel pool = Pool(processes = 6 ) for index, phash in enumerate (pool.imap(create_phash, d, chunksize = 1 )): yield index, phash def detect_hangers(phash_iter, threshold, min_count): """Return list of "hangers" detected in frame_hash_list. A "hanger" is consecutive frames that are the same. frame_hash_list : list of frame hash strings. Frames are considered same or different by counting the differences in their hash strings. threshold : Maximum number of diffences allowed for two frames to be considered "same". min_count : Minimum length of a hanger. Short hangers aren't noticable and don't have to be removed. """ hangers = [] # List of hanger start, stop frame indexes start_index, start_phash = next (phash_iter) for index, phash in phash_iter: print (index, phash) # Are frame and start_frame disimilar enough? if abs (difference_count(start_phash, phash)) > threshold: if index - start_index > = min_count: # Add hanger to list hangers.append((start_index, index - 1 )) start_phash = phash start_index = index # Check if we end with a hanger if index - start_index > 10 : hangers.append((start_index, index)) return hangers def convert_frame_nr_in_time(d): # S8-Movie (avi-file) is checked of hangers ##################################################### # 1 hour contains 72000 frames c1 = 72000 # 1 minute contains 1200 frames c2 = 1200 # 1 second contains 20 frames c3 = 20 def find_even_frame_nr(a, b, c): while True : if a % c = = 0 : break else : a - = 1 b + = 1 return a, b frame_nr_full_hour, rest_1 = find_even_frame_nr(d, 0 , c1) number_of_hours = frame_nr_full_hour / c1 ########################################################### frame_nr_full_minute, rest_2 = find_even_frame_nr(rest_1, 0 , c2) number_of_minutes = frame_nr_full_minute / c2 ########################################################### frame_nr_full_second, rest_3 = find_even_frame_nr(rest_2, 0 , c3) number_of_seconds = frame_nr_full_second / c3 return number_of_hours, number_of_minutes, number_of_seconds def fill_hanger_information_in_excel(hangers, numberOfHangers): pH = "C:\hangerfinder\S8-Hanger_Positionen.xlsm" fileXLSX = openpyxl.load_workbook(pH, keep_vba = True ) sheet = fileXLSX[ "Blatt" ] # find film to check for hangers in excel # film was marked with "x" by me r = 2 for c in range ( 2 , 82 , 4 ): if sheet.cell(r, c).value = = "x" : hanger_start_col = c hanger_end_col = c + 2 # clear old hanger information # film doesn't have more than 100 hangers clear_row = 5 clear_col = hanger_start_col for z in range (clear_row, clear_row + 100 ): for s in range (clear_col, clear_col + 3 ): sheet.cell(row = z, column = s).value = None # fill in hanger information r = 5 for i in hangers: frame_nr_hanger_start = i[ 0 ] frame_nr_hanger_end = i[ 1 ] number_of_hours_start, number_of_minutes_start, number_of_seconds_start = convert_frame_nr_in_time( frame_nr_hanger_start) number_of_hours_end, number_of_minutes_end, number_of_seconds_end = convert_frame_nr_in_time( frame_nr_hanger_end) number_of_hours_start_int = int (number_of_hours_start) number_of_minutes_start_int = int (number_of_minutes_start) number_of_seconds_start_int = int (number_of_seconds_start) number_of_hours_end_int = int (number_of_hours_end) number_of_minutes_end_int = int (number_of_minutes_end) number_of_seconds_end_int = int (number_of_seconds_end) number_of_hours_start_str = str (number_of_hours_start_int) if len (number_of_hours_start_str) = = 1 : number_of_hours_start_str = "0" + number_of_hours_start_str number_of_minutes_start_str = str (number_of_minutes_start_int) if len (number_of_minutes_start_str) = = 1 : number_of_minutes_start_str = "0" + number_of_minutes_start_str number_of_seconds_start_str = str (number_of_seconds_start_int) if len (number_of_seconds_start_str) = = 1 : number_of_seconds_start_str = "0" + number_of_seconds_start_str number_of_hours_end_str = str (number_of_hours_end_int) if len (number_of_hours_end_str) = = 1 : number_of_hours_end_str = "0" + number_of_hours_end_str number_of_minutes_end_str = str (number_of_minutes_end_int) if len (number_of_minutes_end_str) = = 1 : number_of_minutes_end_str = "0" + number_of_minutes_end_str number_of_seconds_end_str = str (number_of_seconds_end_int) if len (number_of_seconds_end_str) = = 1 : number_of_seconds_end_str = "0" + number_of_seconds_end_str # create timestamp timestamp_start_str = number_of_hours_start_str + ":" + number_of_minutes_start_str + ":" + number_of_seconds_start_str timestamp_end_str = number_of_hours_end_str + ":" + number_of_minutes_end_str + ":" + number_of_seconds_end_str hangerNrs = "(" + str (frame_nr_hanger_start) + ", " + str (frame_nr_hanger_end) + ")" hangerNrs_col = hanger_start_col - 1 sheet.cell(row = r, column = hangerNrs_col).value = hangerNrs sheet.cell(row = r, column = hanger_start_col).value = timestamp_start_str sheet.cell(row = r, column = hanger_end_col).value = timestamp_end_str r + = 1 hanger_text_col = hanger_start_col - 1 sheet.cell(row = r, column = hanger_text_col).value = "gefundene Hänger:" sheet.cell(row = r, column = hanger_start_col).value = numberOfHangers fileXLSX.save(pH) fileXLSX.close ctypes.windll.user32.MessageBoxW( 0 , "All hangers were written to excel." , "Cool..." , 1 ) if __name__ = = "__main__" : def button_HF_Start_click(): # check if film is marked with x in excel pH = "C:\hangerfinder\S8-Hanger_Positionen.xlsm" fileXLSX = openpyxl.load_workbook(pH, keep_vba = True ) sheet = fileXLSX[ "Blatt" ] r = 2 xOcurrence = 0 for c in range ( 2 , 82 , 4 ): if sheet.cell(r, c).value = = "x" : xOcurrence = 1 if xOcurrence = = 0 : ctypes.windll.user32.MessageBoxW( 0 , "Please mark the film to be checked for hangers in excel with an " "X" "." , "You forgot something..." , 1 ) sys.exit() begin = time.time() all_frames = os.listdir(p) threshold = textboxThreshold.text() min_count = textboxMinCount.text() hangers = detect_hangers(phash_iter(all_frames), int (threshold), int (min_count)) numberOfHangers = len (hangers) fill_hanger_information_in_excel(hangers, numberOfHangers) end = time.time() print ( 'hangers:' ) print (hangers) print ( 'number of hangers: ' + str (numberOfHangers)) print ( 'time: ' + str (end - begin)) return hangers app = QApplication([sys.argv]) window = QWidget() button_HF_Start = QPushButton( "Hängerfinder ausführen" ) labelThreshold = QLabel() labelThreshold.setText( "erlaubter Unterschied für gleiche Bilder (threshold):" ) textboxThreshold = QLineEdit() textboxThreshold.setText( str ( 0 )) labelMinCount = QLabel() labelMinCount.setText( "kleinster Hänger, der gefunden wird (Anzahl Bilder, min_count):" ) textboxMinCount = QLineEdit() textboxMinCount.setText( str ( 5 )) button_close = QPushButton( "schließen" ) layout = QVBoxLayout() layout.addWidget(labelThreshold) layout.addWidget(textboxThreshold) layout.addWidget(labelMinCount) layout.addWidget(textboxMinCount) layout2 = QHBoxLayout() layout2.addWidget(button_HF_Start) layout2.addWidget(button_close) layout.addLayout(layout2) window.setLayout(layout) window.show() button_HF_Start.clicked.connect(button_HF_Start_click) button_close.clicked.connect(QCoreApplication.instance().quit) sys.exit(app. exec ()) |