3 files modified
7 files added
1 files deleted
New file |
| | |
| | | import numpy as np |
| | | |
| | | def print_binary_pattern_32(x): |
| | | pattern = bin(x)[2:].zfill(32) |
| | | print(x, ':', pattern[0:8], pattern[9:16], pattern[17:24], pattern[25:], len(pattern)) |
| | | |
| | | def to32_np_fn(x: list[np.uint8,np.uint8,np.uint8,np.uint8]): |
| | | y = np.left_shift(x, [np.uint32(0), np.uint32(8), np.uint32(16), np.uint32(24)]) |
| | | return y[0] | y[1] | y[2] | y[3] |
| | | |
| | | |
| | | def to32_bit_op(x: list[np.uint8,np.uint8,np.uint8,np.uint8]): |
| | | # 1 0000_0000 0000_0000 0000_0000 0000_0000 |
| | | mask = (2**32) | (x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0]) |
| | | # remove the most significant bit |
| | | return mask & (2**32-1) |
| | | |
| | | |
| | | def quaternary_8bit_to_unary_32bit(data, to32_fn): |
| | | four_group = np.array(data, dtype=np.uint8).reshape((-1, 4)) |
| | | return np.array([to32_fn(x) for x in four_group]) |
| | | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | raw_data = [255, 0, 15, 170, |
| | | 0b101, 0b1100, 0b1001101, 0b1000_0000, |
| | | 9, 10, 11, 0b1000_0000] |
| | | |
| | | print(f"Konvertierung jeweiliger 4er-Tuple in einem uint32") |
| | | print() |
| | | print("Mit Python built-int Left-Shift-Operator") |
| | | result = quaternary_8bit_to_unary_32bit(raw_data, to32_np_fn) |
| | | for r in result: |
| | | print_binary_pattern_32(r) |
| | | |
| | | print() |
| | | print("Mit numpy left_shift Funktion") |
| | | result = quaternary_8bit_to_unary_32bit(raw_data, to32_bit_op) |
| | | for r in result: |
| | | print_binary_pattern_32(r) |
New file |
| | |
| | | # Demonstration von Zusammenspiel numpy/PIL und PySide6 |
| | | |
| | | ## Build python file from ui |
| | | |
| | | ```shell |
| | | pyside6-project build imgdemo.json |
| | | ``` |
| | | |
| | | ## Install as development mode (editable) |
| | | |
| | | ``` |
| | | pip install -e . |
| | | ``` |
| | | |
| | | ## Run the application after install |
| | | |
| | | |
| | | ``` |
| | | imgdemo |
| | | ``` |
New file |
| | |
| | | [build-system] |
| | | requires = ["setuptools"] |
| | | build-backend = "setuptools.build_meta" |
| | | |
| | | [project] |
| | | name = "image-demo" |
| | | version = "0.0.1" |
| | | dependencies = [ |
| | | "numpy >= 2.0.0", |
| | | "matplotlib >= 3.9", |
| | | "PySide6 >= 6.7" |
| | | ] |
| | | |
| | | [tool.setuptools.packages.find] |
| | | # All the following settings are optional: |
| | | where = ["src"] |
| | | |
| | | [project.gui-scripts] |
| | | imgdemo = "imgdemo.guimain:main" |
New file |
| | |
| | | import sys |
| | | |
| | | from PySide6.QtGui import QPixmap, QImage |
| | | #from PIL.ImageQt import QPixmap, QImage |
| | | |
| | | from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog |
| | | import numpy as np |
| | | from PIL import Image |
| | | |
| | | from imgdemo.ui_mainwindow import Ui_MainWindow |
| | | |
| | | class MainWindow(QMainWindow): |
| | | def __init__(self): |
| | | super(MainWindow, self).__init__() |
| | | self.saved_file = ('', '') |
| | | self.chosen_file = ('', '') |
| | | self.ui = Ui_MainWindow() |
| | | self.ui.setupUi(self) |
| | | self.ui.actionChoose_Image.triggered.connect(self.choose_image) |
| | | self.ui.actionSave_Image.triggered.connect(self.save_image) |
| | | |
| | | def choose_image(self): |
| | | self.chosen_file = ('', '') # reset (for safe) |
| | | self.chosen_file = QFileDialog.getOpenFileName(None, "Choose Image", "", |
| | | "Images (*.png *.xpm *.jpg *.tiff) ;; All Filetypes (*.*)") |
| | | print(self.chosen_file) |
| | | if self.chosen_file[0] != '': # user has chosen a file |
| | | self.display_image() |
| | | |
| | | |
| | | def save_image(self): |
| | | self.saved_file = ('', '') # reset for safe |
| | | self.saved_file = QFileDialog.getSaveFileName(None, "Choose Image", "", |
| | | "All (*.*)") |
| | | print(self.saved_file) |
| | | |
| | | |
| | | def display_image(self): |
| | | pixmap = QPixmap(self.chosen_file[0]) |
| | | self.ui.origin_img.setPixmap(pixmap) |
| | | # now read the image and show it via Image in other container |
| | | with Image.open(self.chosen_file[0]) as img: |
| | | image = np.asarray(img, dtype=np.uint8) |
| | | self.display_numpy_image(image) |
| | | |
| | | |
| | | def display_numpy_image(self, image): |
| | | height, width, channel = image.shape |
| | | print(height, width, channel) |
| | | |
| | | bytes_per_line = channel * width # color |
| | | img_format = QImage.Format.Format_RGBX8888 |
| | | if channel == 4: |
| | | img_format = QImage.Format.Format_ARGB32 |
| | | elif channel == 3: |
| | | img_format = QImage.Format.Format_RGB888 |
| | | qImg = QImage(image.data, width, height, bytes_per_line, img_format).rgbSwapped() |
| | | pixmap = QPixmap(qImg) |
| | | self.ui.result_img.setPixmap(pixmap) |
| | | |
| | | |
| | | |
| | | |
| | | def main(): |
| | | app = QApplication(sys.argv) |
| | | window = MainWindow() |
| | | window.show() |
| | | |
| | | sys.exit(app.exec()) |
| | | pass |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | main() |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <ui version="4.0"> |
| | | <class>MainWindow</class> |
| | | <widget class="QMainWindow" name="MainWindow"> |
| | | <property name="geometry"> |
| | | <rect> |
| | | <x>0</x> |
| | | <y>0</y> |
| | | <width>800</width> |
| | | <height>600</height> |
| | | </rect> |
| | | </property> |
| | | <property name="windowTitle"> |
| | | <string>Image Demo</string> |
| | | </property> |
| | | <widget class="QWidget" name="centralwidget"> |
| | | <layout class="QVBoxLayout" name="verticalLayout_3"> |
| | | <item> |
| | | <layout class="QHBoxLayout" name="horizontalLayout"> |
| | | <item> |
| | | <widget class="QGroupBox" name="origin_container"> |
| | | <property name="title"> |
| | | <string>Origin Image</string> |
| | | </property> |
| | | <layout class="QVBoxLayout" name="verticalLayout_2"> |
| | | <item> |
| | | <widget class="QLabel" name="origin_img"> |
| | | <property name="text"> |
| | | <string>Source</string> |
| | | </property> |
| | | </widget> |
| | | </item> |
| | | </layout> |
| | | </widget> |
| | | </item> |
| | | <item> |
| | | <widget class="QGroupBox" name="result_container"> |
| | | <property name="title"> |
| | | <string>Filtered Image</string> |
| | | </property> |
| | | <layout class="QVBoxLayout" name="verticalLayout"> |
| | | <item> |
| | | <widget class="QLabel" name="result_img"> |
| | | <property name="text"> |
| | | <string>Result</string> |
| | | </property> |
| | | </widget> |
| | | </item> |
| | | </layout> |
| | | </widget> |
| | | </item> |
| | | </layout> |
| | | </item> |
| | | <item> |
| | | <widget class="QPushButton" name="pushButton"> |
| | | <property name="text"> |
| | | <string>Dummy Widget</string> |
| | | </property> |
| | | </widget> |
| | | </item> |
| | | </layout> |
| | | </widget> |
| | | <widget class="QMenuBar" name="menubar"> |
| | | <property name="geometry"> |
| | | <rect> |
| | | <x>0</x> |
| | | <y>0</y> |
| | | <width>800</width> |
| | | <height>22</height> |
| | | </rect> |
| | | </property> |
| | | <widget class="QMenu" name="menuFile"> |
| | | <property name="title"> |
| | | <string>&File</string> |
| | | </property> |
| | | <addaction name="actionChoose_Image"/> |
| | | <addaction name="actionSave_Image"/> |
| | | </widget> |
| | | <addaction name="menuFile"/> |
| | | </widget> |
| | | <widget class="QStatusBar" name="statusbar"/> |
| | | <action name="actionChoose_Image"> |
| | | <property name="icon"> |
| | | <iconset theme="QIcon::ThemeIcon::FolderOpen"/> |
| | | </property> |
| | | <property name="text"> |
| | | <string>Choose Image</string> |
| | | </property> |
| | | <property name="shortcut"> |
| | | <string>Ctrl+O</string> |
| | | </property> |
| | | </action> |
| | | <action name="actionSave_Image"> |
| | | <property name="icon"> |
| | | <iconset theme="QIcon::ThemeIcon::DocumentSave"/> |
| | | </property> |
| | | <property name="text"> |
| | | <string>Save Image</string> |
| | | </property> |
| | | <property name="shortcut"> |
| | | <string>Ctrl+S</string> |
| | | </property> |
| | | </action> |
| | | </widget> |
| | | <resources/> |
| | | <connections/> |
| | | </ui> |
New file |
| | |
| | | # -*- coding: utf-8 -*- |
| | | |
| | | ################################################################################ |
| | | ## Form generated from reading UI file 'mainwindow.ui' |
| | | ## |
| | | ## Created by: Qt User Interface Compiler version 6.7.2 |
| | | ## |
| | | ## WARNING! All changes made in this file will be lost when recompiling UI file! |
| | | ################################################################################ |
| | | |
| | | from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, |
| | | QMetaObject, QObject, QPoint, QRect, |
| | | QSize, QTime, QUrl, Qt) |
| | | from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient, |
| | | QCursor, QFont, QFontDatabase, QGradient, |
| | | QIcon, QImage, QKeySequence, QLinearGradient, |
| | | QPainter, QPalette, QPixmap, QRadialGradient, |
| | | QTransform) |
| | | from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel, |
| | | QMainWindow, QMenu, QMenuBar, QPushButton, |
| | | QSizePolicy, QStatusBar, QVBoxLayout, QWidget) |
| | | |
| | | class Ui_MainWindow(object): |
| | | def setupUi(self, MainWindow): |
| | | if not MainWindow.objectName(): |
| | | MainWindow.setObjectName(u"MainWindow") |
| | | MainWindow.resize(800, 600) |
| | | self.actionChoose_Image = QAction(MainWindow) |
| | | self.actionChoose_Image.setObjectName(u"actionChoose_Image") |
| | | icon = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.FolderOpen)) |
| | | self.actionChoose_Image.setIcon(icon) |
| | | self.actionSave_Image = QAction(MainWindow) |
| | | self.actionSave_Image.setObjectName(u"actionSave_Image") |
| | | icon1 = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.DocumentSave)) |
| | | self.actionSave_Image.setIcon(icon1) |
| | | self.centralwidget = QWidget(MainWindow) |
| | | self.centralwidget.setObjectName(u"centralwidget") |
| | | self.verticalLayout_3 = QVBoxLayout(self.centralwidget) |
| | | self.verticalLayout_3.setObjectName(u"verticalLayout_3") |
| | | self.horizontalLayout = QHBoxLayout() |
| | | self.horizontalLayout.setObjectName(u"horizontalLayout") |
| | | self.origin_container = QGroupBox(self.centralwidget) |
| | | self.origin_container.setObjectName(u"origin_container") |
| | | self.verticalLayout_2 = QVBoxLayout(self.origin_container) |
| | | self.verticalLayout_2.setObjectName(u"verticalLayout_2") |
| | | self.origin_img = QLabel(self.origin_container) |
| | | self.origin_img.setObjectName(u"origin_img") |
| | | |
| | | self.verticalLayout_2.addWidget(self.origin_img) |
| | | |
| | | |
| | | self.horizontalLayout.addWidget(self.origin_container) |
| | | |
| | | self.result_container = QGroupBox(self.centralwidget) |
| | | self.result_container.setObjectName(u"result_container") |
| | | self.verticalLayout = QVBoxLayout(self.result_container) |
| | | self.verticalLayout.setObjectName(u"verticalLayout") |
| | | self.result_img = QLabel(self.result_container) |
| | | self.result_img.setObjectName(u"result_img") |
| | | |
| | | self.verticalLayout.addWidget(self.result_img) |
| | | |
| | | |
| | | self.horizontalLayout.addWidget(self.result_container) |
| | | |
| | | |
| | | self.verticalLayout_3.addLayout(self.horizontalLayout) |
| | | |
| | | self.pushButton = QPushButton(self.centralwidget) |
| | | self.pushButton.setObjectName(u"pushButton") |
| | | |
| | | self.verticalLayout_3.addWidget(self.pushButton) |
| | | |
| | | MainWindow.setCentralWidget(self.centralwidget) |
| | | self.menubar = QMenuBar(MainWindow) |
| | | self.menubar.setObjectName(u"menubar") |
| | | self.menubar.setGeometry(QRect(0, 0, 800, 22)) |
| | | self.menuFile = QMenu(self.menubar) |
| | | self.menuFile.setObjectName(u"menuFile") |
| | | MainWindow.setMenuBar(self.menubar) |
| | | self.statusbar = QStatusBar(MainWindow) |
| | | self.statusbar.setObjectName(u"statusbar") |
| | | MainWindow.setStatusBar(self.statusbar) |
| | | |
| | | self.menubar.addAction(self.menuFile.menuAction()) |
| | | self.menuFile.addAction(self.actionChoose_Image) |
| | | self.menuFile.addAction(self.actionSave_Image) |
| | | |
| | | self.retranslateUi(MainWindow) |
| | | |
| | | QMetaObject.connectSlotsByName(MainWindow) |
| | | # setupUi |
| | | |
| | | def retranslateUi(self, MainWindow): |
| | | MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Image Demo", None)) |
| | | self.actionChoose_Image.setText(QCoreApplication.translate("MainWindow", u"Choose Image", None)) |
| | | #if QT_CONFIG(shortcut) |
| | | self.actionChoose_Image.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+O", None)) |
| | | #endif // QT_CONFIG(shortcut) |
| | | self.actionSave_Image.setText(QCoreApplication.translate("MainWindow", u"Save Image", None)) |
| | | #if QT_CONFIG(shortcut) |
| | | self.actionSave_Image.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+S", None)) |
| | | #endif // QT_CONFIG(shortcut) |
| | | self.origin_container.setTitle(QCoreApplication.translate("MainWindow", u"Origin Image", None)) |
| | | self.origin_img.setText(QCoreApplication.translate("MainWindow", u"Source", None)) |
| | | self.result_container.setTitle(QCoreApplication.translate("MainWindow", u"Filtered Image", None)) |
| | | self.result_img.setText(QCoreApplication.translate("MainWindow", u"Result", None)) |
| | | self.pushButton.setText(QCoreApplication.translate("MainWindow", u"Dummy Widget", None)) |
| | | self.menuFile.setTitle(QCoreApplication.translate("MainWindow", u"&File", None)) |
| | | # retranslateUi |
| | | |
| | |
| | | |
| | | |
| | | class Graph: |
| | | """ |
| | | represents an undirected and unweighted Graph |
| | | """ |
| | | def __init__(self): |
| | | self._adjacent: dict[int, set] = {} |
| | | self._vertex_attribute: dict[int, dict] = {} |
| | |
| | | u_neighbor.add(v) |
| | | pass |
| | | |
| | | def add_edges(self, u: int, adjacent:[int]): |
| | | def add_edges(self, u: int, adjacent: list[int]): |
| | | for v in adjacent: |
| | | self.add_edge(u, v) |
| | | pass |
| | |
| | | """ |
| | | if vertex not in self._adjacent: |
| | | raise ValueError(f"Graph does not include vertex {vertex}") |
| | | old_attributes = self._vertex_attribute.get(vertex) |
| | | old_attributes = self._vertex_attribute[vertex] |
| | | self._vertex_attribute[vertex] = old_attributes | properties |
| | | return self |
| | | pass |
| | |
| | | def adjacent_of(self, vertex: int): |
| | | if vertex not in self._adjacent: |
| | | raise ValueError(f"Graph does not include vertex {vertex}") |
| | | return sorted( self._adjacent.get(vertex) ) |
| | | return sorted( self._adjacent[vertex] ) |
| | | |
| | | def for_each_edges(self, action: Callable[[int, int], Any]): |
| | | """ |
| | |
| | | for end in self.adjacent_of(start): |
| | | (first, second) = (start, end) if (start >= end) else (end, start) |
| | | if first in visited_edges: |
| | | visited_adjacent = visited_edges.get(first) |
| | | #visited_adjacent = visited_edges.get(first) |
| | | visited_adjacent = visited_edges[first] |
| | | if second not in visited_adjacent: |
| | | visited_adjacent.add(second) |
| | | action(start, end) |
| | | else: |
| | | adjacent = set() |
| | | adjacent: set[int] = set() |
| | | visited_edges[first] = adjacent |
| | | adjacent.add(second) |
| | | action(start, end) |
| | | |
| | | def get_lecture_name(self, vertex: int): |
| | | pass |
| | | |
| | | def set_lecture_name(self, vertex: int, name: str): |
| | | pass |
| | | |
| | | def __repr__(self): |
| | | text = "" |
| | |
| | | import collections |
| | | from typing import Mapping |
| | | |
| | | from pygraph.graphdemo import Graph |
| | | |
| | | |
| | | def bfs(g: Graph, start: int) -> {int:int|None}: |
| | | def bfs(g: Graph, start: int) -> Graph: |
| | | """ |
| | | |
| | | :param g: |
| | |
| | | g.merge_attribute(v, visited) |
| | | queue.append(v) |
| | | return tree |
| | | |
| | | |
| | | def bfs_dict(g: Graph, start: int) -> Mapping[int, int|None]: |
| | | tree = {start:None} |
| | | queue = collections.deque() |
| | | VISITED = "visited" |
| | | not_visited = {VISITED: False} |
| | | visited = {VISITED: True} |
| | | g.for_each_vertices(lambda v : g.merge_attribute(v, not_visited)) |
| | | queue.append(start) # append() is the enqueue() operation of a Queue |
| | | g.merge_attribute(start, visited) |
| | | while queue: |
| | | u = queue.popleft() # popleft() is the dequeue() operation of a Queue |
| | | for v in g.adjacent_of(u): |
| | | if not g.get_attribute(v)[VISITED]: |
| | | tree[v] = u |
| | | g.merge_attribute(v, visited) |
| | | queue.append(v) |
| | | return tree |
| | | pass |
| | | |
| | | |
| | | def find_path(g: Graph, u: int, v: int) -> list[int]: |
| | | tree = bfs_dict(g, v) |
| | | path = [u] |
| | | while (current := path[-1]) != v: |
| | | precedent = tree[current] |
| | | path.append(precedent) |
| | | return path |
| | | |
| | | |
| | | def find_path_gpt(g: Graph, u: int, v: int) -> list[int]: |
| | | # Erstelle einen BFS-Baum, beginnend bei Knoten v |
| | | bfs_tree = bfs_dict(g, v) |
| | | |
| | | # Wenn u nicht in bfs_tree ist, gibt es keinen Pfad von u nach v |
| | | if u not in bfs_tree: |
| | | return [] # Kein Pfad gefunden |
| | | |
| | | # Den Pfad von u nach v rekonstruieren |
| | | path = [] |
| | | current = u |
| | | while current is not None: |
| | | path.append(current) |
| | | current = bfs_tree[current] |
| | | |
| | | # Den Pfad umkehren, da wir rückwärts von u nach v gehen |
| | | path.reverse() |
| | | |
| | | return path |
| | |
| | | import unittest |
| | | |
| | | from pygraph.graphdemo import Graph |
| | | from pygraph.shortestpath import bfs |
| | | from pygraph.shortestpath import bfs, bfs_dict, find_path, find_path_gpt |
| | | |
| | | |
| | | class ShortestPathTestCase(unittest.TestCase): |
| | | def test_bfs(self): |
| | | g = Graph() |
| | | g.add_edges(0, [1, 2]) |
| | | g.add_edges(1, [0, 3, 4]) |
| | | g.add_edges(2, [0, 4, 6, 7]) |
| | | g.add_edges(3, [1]) |
| | | g.add_edges(4, [1, 2, 5]) |
| | | g.add_edges(5, [4]) |
| | | g.add_edges(6, [2]) |
| | | g.add_edges(7, [2]) |
| | | #print(g) |
| | | # self.assertEqual(True, False) # add assertion here |
| | | |
| | | g.add_edges(1, [3, 4]) |
| | | g.add_edges(2, [4, 6, 7]) |
| | | g.add_edges(4, [5]) |
| | | print(g) |
| | | print("#") |
| | | tree = bfs(g, 0) |
| | | print(tree) |
| | | |
| | | def test_bfs_dict(self): |
| | | g = Graph() |
| | | g.add_edges(0, [1, 2]) |
| | | g.add_edges(1, [3, 4]) |
| | | g.add_edges(2, [4, 6, 7]) |
| | | g.add_edges(4, [5]) |
| | | print(g) |
| | | tree = bfs_dict(g, 6) |
| | | print("Tree from Vertex 6") |
| | | print(tree) |
| | | |
| | | def test_find_path(self): |
| | | g = Graph() |
| | | g.add_edges(0, [1, 2]) |
| | | g.add_edges(1, [3, 4]) |
| | | g.add_edges(2, [4, 6, 7]) |
| | | g.add_edges(4, [5]) |
| | | print(g) |
| | | (u, v) = (6, 5) |
| | | path = find_path(g, 6, 5) |
| | | print(f"path from {u} to {v}") |
| | | print(path) |
| | | |
| | | def test_find_path_gpt(self): |
| | | g = Graph() |
| | | g.add_edges(0, [1, 2]) |
| | | g.add_edges(1, [3, 4]) |
| | | g.add_edges(2, [4, 6, 7]) |
| | | g.add_edges(4, [5]) |
| | | print(g) |
| | | (u, v) = (6, 5) |
| | | path = find_path_gpt(g, 6, 5) |
| | | print(f"path from {u} to {v}") |
| | | print(path) |
| | | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | unittest.main() |