Posts: 130
Threads: 30
Joined: May 2020
Apr-26-2023, 11:32 AM
(This post was last modified: Apr-26-2023, 11:36 AM by buran.)
Dear community,
I want to use the 3 pHash functions (ph_dct_imagehash, ph_image_digest and ph_mh_imagehash) to compare which fits best for me...
I tried it many hours (install problems..., searching the web...) but now I can't go any further...
I can call the 2 functions ph_image_digest and ph_dct_imagehash, ph_mh_imagehash is not available.
But when I run the script, it is mentioned:
Error: Traceback (most recent call last):
File "D:\programmierOrdner\python-Programmierung\hangerfinder\main.py", line 7, in <module>
from phash import ph_image_digest
File "C:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\phash\__init__.py", line 4, in <module>
from .phash_ctypes import *
File "C:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\phash\phash_ctypes.py", line 17, in <module>
raise ImportError('Cannot find libpHash!')
ImportError: Cannot find libpHash!
I tried very long to install libpHash - witout any success...
How can I fix the importError "ImportError: Cannot find libpHash!"?
Could you please help me out?
import os
import time
import ctypes
from multiprocessing import Pool
from PIL import Image
from phash import ph_image_digest
from phash import ph_dct_imagehash
from phash import ph_crosscorr
p = "D:/S8_hanger_finder/neuer_Ansatz/phash_test/"
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(ph_image_digest(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 difference_count(a: str, b: str) -> int:
# count differences between a and b
return ph_crosscorr(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: int = 0, min_count: int = 4):
"""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 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
if __name__ == "__main__":
begin = time.time()
all_frames = os.listdir(p)
hangers = detect_hangers(phash_iter(all_frames))
end = time.time()
print('hangers:')
print(hangers)
numberOfHangers = len(hangers)
print('number of hangers: ' + str(numberOfHangers))
print('time: ' + str(end - begin))
Posts: 6,221
Threads: 16
Joined: Feb 2020
Did you go to the package homepage?
https://github.com/JohannesBuchner/imagehash
Quote:Installation
Based on PIL/Pillow Image, numpy and scipy.fftpack (for pHash) Easy installation through pypi:
Do you have numpy and scipy.fftpack installed?
Posts: 130
Threads: 30
Joined: May 2020
Apr-28-2023, 06:09 AM
(This post was last modified: Apr-28-2023, 04:51 PM by flash77.)
Hi,
I did everything but the error remains...
Greetings,
flash77
Posts: 130
Threads: 30
Joined: May 2020
Apr-28-2023, 04:54 PM
(This post was last modified: Apr-28-2023, 04:54 PM by flash77.)
Dear community,
I would like to test the 3 hash functions (ph_dct_imagehash, ph_image_digest and ph_mh_imagehash) to know which one works well for my needs.
I tried it many hours but now I can't go any further...
How can I fix the importError "ImportError: Cannot find libpHash!"?
I would be very happy about hints, because I don't know exactly why the package is not found.
I'm using Pycharm and a virtual enviroment.
I hereby attach the error messages that appear in Pycharm - please have a look.
Thanks for your help...
Have a nice weekend...
Posts: 6,221
Threads: 16
Joined: Feb 2020
Apr-28-2023, 07:18 PM
(This post was last modified: Apr-28-2023, 07:18 PM by deanhystad.)
Please post errors as text, not screenshots. I cannot cut/paste text from a screenshot.
Posts: 7,091
Threads: 122
Joined: Sep 2016
Apr-29-2023, 12:51 PM
(This post was last modified: Apr-29-2023, 12:51 PM by snippsat.)
Should find a alternative to python-phash it's old and documentation dos not work.
Most run Makefile with a C/C++ complier and link to libpHash,none of this is documented or for sure never tested on Windows.
Code has been unmaintained for 8-years.
Posts: 130
Threads: 30
Joined: May 2020
Hello deanhystad, hello snippsat, thanks for your replies. Unfortunately I wasn't able to look into the forum earlier. I'll paste the error messages as text tomorrow when I get back to work.
I wish a nice evening...
Posts: 6,221
Threads: 16
Joined: Feb 2020
Don't waste your time posting error message. I wrote my reply thinking you were using a different phash package. snippsat provided the correct answer to your problem; use a package that is up-to-date and maintained.
Posts: 130
Threads: 30
Joined: May 2020
Dear community,
with the great support of this forum I made a perceptual-hash-hanger-finder for digitized super8-films.
Thanks a lot for helping me so much...
As a final step, I'm trying to get a PyQt6 dialog. I have the following problem:
In line 159 I created a function:
def button_HF_Start_click():
If I click on the button of the dialog, then the hangerfinder is executed.
But when I close the dialog, the hangerfinder is run again. At the moment I'm stuck...
Maybe someone can give me a hint...
Thanks very much!!
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QVBoxLayout
import os
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: int = 0, min_count: int = 5):
"""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):
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
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
fileXLSX.save(pH)
fileXLSX.close
def button_HF_Start_click():
begin = time.time()
all_frames = os.listdir(p)
hangers = detect_hangers(phash_iter(all_frames))
end = time.time()
print('hangers:')
print(hangers)
numberOfHangers = len(hangers)
print('number of hangers: ' + str(numberOfHangers))
print('time: ' + str(end - begin))
return hangers
if __name__ == "__main__":
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
button_HF_Start = QPushButton("Hängerfinder ausführen")
layout.addWidget(button_HF_Start)
window.setLayout(layout)
button_HF_Start.clicked.connect(button_HF_Start_click)
window.show()
app.exec()
hangers = button_HF_Start_click()
fill_hanger_information_in_excel(hangers)
Posts: 130
Threads: 30
Joined: May 2020
May-16-2023, 11:21 AM
(This post was last modified: May-16-2023, 11:32 AM by flash77.)
Hi,
this works:
def button_HF_Start_click():
begin = time.time()
all_frames = os.listdir(p)
threshold = textboxT.text()
min_count = textboxM.text()
hangers = detect_hangers(phash_iter(all_frames), int(threshold), int(min_count))
fill_hanger_information_in_excel(hangers)
end = time.time()
print('hangers:')
print(hangers)
numberOfHangers = len(hangers)
print('number of hangers: ' + str(numberOfHangers))
print('time: ' + str(end - begin))
return hangers
if __name__ == "__main__":
app = QApplication([sys.argv])
window = QWidget()
button_HF_Start = QPushButton("Hängerfinder ausführen")
textboxT = QLineEdit()
textboxM = QLineEdit()
layout = QVBoxLayout()
layout.addWidget(button_HF_Start)
layout.addWidget(textboxT)
layout.addWidget(textboxM)
window.setLayout(layout)
window.show()
button_HF_Start.clicked.connect(button_HF_Start_click)
sys.exit(app.exec())
|