Skip to content

Commit

Permalink
face-recognition working
Browse files Browse the repository at this point in the history
  • Loading branch information
rafay-pk committed May 5, 2023
1 parent 0af2b26 commit d2e4c60
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 88 deletions.
48 changes: 45 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sys, os, pathlib, sqlite3
import sys, os, pathlib, sqlite3, face_recognition, threading
from PyQt6.QtCore import Qt, QSize, QDir, QSize, QUrl, QStringListModel, QItemSelectionModel, QSortFilterProxyModel, QModelIndex
from PyQt6.QtGui import QFileSystemModel, QPixmap, QMovie, QIcon, QAction, QImage, QStandardItemModel, QStandardItem
from PyQt6.QtMultimedia import QMediaPlayer
Expand All @@ -22,13 +22,14 @@
QScrollArea,
QSplitter,
QAbstractItemView,
QListView,
QListView,
QMenu
)


class SQLiteDB:
def __init__(self, db_path):
self.conn = sqlite3.connect(db_path)
self.conn = sqlite3.connect(db_path, check_same_thread=False)
self.cursor = self.conn.cursor()

def execute_query_from_file(self, file_path):
Expand Down Expand Up @@ -193,10 +194,13 @@ def __init__(self):
self.clear_btn.setIcon(QIcon("icons/clear.png"))
self.clear_btn.setShortcut("Esc")
self.clear_btn.pressed.connect(self.clear)
# self.ai_process_btn = QPushButton("AI Process")
# self.ai_process_btn.pressed.connect(self.ai_process)
searchLayout = QHBoxLayout()
searchLayout.addWidget(self.search_bar)
searchLayout.addWidget(self.clear_btn)
searchLayout.addWidget(self.search_enter)
# searchLayout.addWidget(self.ai_process_btn)
searchLayout.setContentsMargins(0, 0, 0, 0)
searchLayout.setSpacing(0)
searchBar = QWidget()
Expand Down Expand Up @@ -231,6 +235,8 @@ def __init__(self):
self.folders.setSortingEnabled(True)
self.folders.selectionModel().selectionChanged.connect(self.folder_selected)
self.folders.setSelectionMode(QAbstractItemView.SelectionMode.ContiguousSelection)
self.folders.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.folders.customContextMenuRequested.connect(self.folder_context_menu)
# endregion

# region Browser View
Expand Down Expand Up @@ -340,6 +346,13 @@ def __init__(self):
# endregion

# region Mechanics
def folder_context_menu(self, pos):
menu = QMenu()
action1 = QAction("Process Folder", self)
action1.triggered.connect(self.ai_process_folder_start)
menu.addAction(action1)
menu.exec(self.folders.viewport().mapToGlobal(pos))

def clear(self):
self.search_bar.clear()
self.tag_bar.clear()
Expand Down Expand Up @@ -421,6 +434,35 @@ def search(self, tags):
self.browser_detailView.add_strings(self.sql_search_inclusive(tagList))
self.update_title(tagString)

# def ai_process(self):
# path = self.browser_detailView.get_selected_text()
# self.status.showMessage(f"AI Processing {path} - Started")
# _, extension = os.path.splitext(path)
# if self.filetype_switcher[extension].__name__ != self.display_static.__name__:
# self.status.showMessage(f"AI Processing - Unsupported file type - {extension}")
# else:
# image = face_recognition.load_image_file(path)
# face_locations = face_recognition.face_locations(image)
# print(face_locations)
# self.status.showMessage("AI Processing - Finished")

def ai_process_folder_start(self):
thread = threading.Thread(target=self.ai_process_folder)
thread.start()

def ai_process_folder(self):
for index in self.folders.selectedIndexes():
sym_path = self.fileSystem.filePath(index)
org_path = self.sql_get_files_in_folder(sym_path)
for file in [f'{self.file_op(root)}/{f}' for root, dir, file in os.walk(org_path) for f in file]:
self.status.showMessage(f"AI Processing - {file}")
_, extension = os.path.splitext(file)
if self.filetype_switcher[extension].__name__ != self.display_static.__name__:
continue
image = face_recognition.load_image_file(file)
print(face_recognition.face_encodings(image, num_jitters=5, model="large"))
self.status.showMessage(f"AI Processing - {org_path} - Finished")

def show_about(self):
self.about = AboutWindow()
self.about.show()
Expand Down
226 changes: 141 additions & 85 deletions test.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,146 @@
import sys
from PyQt6.QtCore import Qt, QModelIndex, QSortFilterProxyModel
from PyQt6.QtGui import QStandardItemModel, QStandardItem
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QListView

class QDetailListView(QListView):
def __init__(self, parent=None):
super().__init__(parent)

self.setSelectionMode(QListView.SelectionMode.SingleSelection)

self.model = QStandardItemModel()
self.setModel(self.model)

self.sort_proxy_model = QSortFilterProxyModel()
self.sort_proxy_model.setSourceModel(self.model)
self.sort_proxy_model.setSortRole(Qt.ItemDataRole.DisplayRole)
self.sort_proxy_model.sort(0, Qt.SortOrder.AscendingOrder)

self.setModel(self.sort_proxy_model)

self.items = set()

def setSelectionChangedFunction(self, func):
self.selectionModel().selectionChanged.connect(func)

def add_strings(self, string_list):
for string in [s for s in string_list if s not in self.items]:
self.items.add(string)
self.model.appendRow(QStandardItem(string))

def clear(self):
self.model.clear()
self.items.clear()
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *

import time
import traceback, sys


class WorkerSignals(QObject):
'''
Defines the signals available from a running worker thread.
Supported signals are:
finished
No data
error
tuple (exctype, value, traceback.format_exc() )
result
object data returned from processing, anything
progress
int indicating % progress
'''
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(int)


class Worker(QRunnable):
'''
Worker thread
Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
:param callback: The function callback to run on this worker thread. Supplied args and
kwargs will be passed through to the runner.
:type callback: function
:param args: Arguments to pass to the callback function
:param kwargs: Keywords to pass to the callback function
'''

def __init__(self, fn, *args, **kwargs):
super(Worker, self).__init__()

# Store constructor arguments (re-used for processing)
self.fn = fn
self.args = args
self.kwargs = kwargs
self.signals = WorkerSignals()

# Add the callback to our kwargs
self.kwargs['progress_callback'] = self.signals.progress

@pyqtSlot()
def run(self):
'''
Initialise the runner function with passed args, kwargs.
'''

# Retrieve args/kwargs here; and fire processing using them
try:
result = self.fn(*self.args, **self.kwargs)
except:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
self.signals.result.emit(result) # Return the result of the processing
finally:
self.signals.finished.emit() # Done



class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.setWindowTitle("Detail List View Example")
self.setGeometry(100, 100, 500, 500)

# create a central widget and layout
central_widget = QWidget()
self.setCentralWidget(central_widget)


def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)

self.counter = 0

layout = QVBoxLayout()
central_widget.setLayout(layout)

# create the DetailListView object
self.browser_detailView = DetailListView(self)

# set the data of the DetailListView to an initial set of strings
# data_set = {"apple", "banana", "orange", "pear"}
# self.browser_detailView.set_data(data_set)

# create a button to add strings to the DetailListView
add_button = QPushButton("Add Strings")
add_button.clicked.connect(self.add_strings)

# create a button to clear the contents of the DetailListView
clear_button = QPushButton("Clear")
clear_button.clicked.connect(self.browser_detailView.clear)

# add the DetailListView and buttons to the layout
layout.addWidget(self.browser_detailView)
layout.addWidget(add_button)
layout.addWidget(clear_button)
self.x = 0

self.l = QLabel("Start")
b = QPushButton("DANGER!")
b.pressed.connect(self.oh_no)

layout.addWidget(self.l)
layout.addWidget(b)

w = QWidget()
w.setLayout(layout)

self.setCentralWidget(w)

self.show()

def add_strings(self):
# create a large list of unique strings
if self.x == 0:
string_list = ["apple", "banana", "orange", "kiwi"]
else:
string_list = ["apple", "banana", "ass", "kiwi"]


# add the list of strings to the DetailListView
self.browser_detailView.add_strings(string_list)
self.x += 1

if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

self.threadpool = QThreadPool()
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

self.timer = QTimer()
self.timer.setInterval(1000)
self.timer.timeout.connect(self.recurring_timer)
self.timer.start()

def progress_fn(self, n):
print("%d%% done" % n)

def execute_this_fn(self, progress_callback):
for n in range(0, 5):
time.sleep(1)
progress_callback.emit(n*100/4)

return "Done."

def print_output(self, s):
print(s)

def thread_complete(self):
print("THREAD COMPLETE!")

def oh_no(self):
# Pass the function to execute
worker = Worker(self.execute_this_fn) # Any other args, kwargs are passed to the run function
worker.signals.result.connect(self.print_output)
worker.signals.finished.connect(self.thread_complete)
worker.signals.progress.connect(self.progress_fn)

# Execute
self.threadpool.start(worker)


def recurring_timer(self):
self.counter +=1
self.l.setText("Counter: %d" % self.counter)


app = QApplication([])
window = MainWindow()
app.exec()

0 comments on commit d2e4c60

Please sign in to comment.