Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bilinear #115

Merged
merged 5 commits into from
Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
.
  • Loading branch information
miguel-martinr committed Jan 6, 2022
commit 6fa4a9fd408e9e781a222eecd3ae132b76b7313e
23 changes: 16 additions & 7 deletions src/pycture/commands/edit_commands/interpolation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

from PyQt5.QtGui import QImage
from math import floor, sqrt
import numpy as np

def nearest_neighbor_interpolation(image: QImage, point: (float, float)):
_x, _y = point
Expand All @@ -11,8 +12,9 @@ def nearest_neighbor_interpolation(image: QImage, point: (float, float)):
Y = floor(_y)
Y_one = min(Y + 1, image.height() - 1)


# top left top right bottom left bottom right
corners = ((X, Y_one), (X_one, Y_one), (X, Y), (X_one, Y))
corners = ((X, Y), (X_one, Y), (X, Y_one), (X_one, Y_one))

distances = [sqrt((x - _x)**2 + (y - _y)**2)
for x, y in corners]
Expand All @@ -23,24 +25,31 @@ def nearest_neighbor_interpolation(image: QImage, point: (float, float)):
def bilinear_interpolation(image: QImage, point: (float, float)):
_x, _y = point

def get_rgb(pixel):
return pixel & 0x00ffffff

X = floor(_x)
X_one = min(X + 1, image.width() - 1)

Y = floor(_y)
Y_one = min(Y + 1, image.height() - 1)

A = image.pixel(X, Y_one) # top left
B = image.pixel(X_one, Y_one) # top right
C = image.pixel(X, Y) # bottom left
D = image.pixel(X_one, Y) # bottom right
A = get_rgb(image.pixel(X, Y)) # top left
B = get_rgb(image.pixel(X_one, Y)) # top right
C = get_rgb(image.pixel(X, Y_one)) # bottom left
D = get_rgb(image.pixel(X_one, Y_one)) # bottom right

p = _x - X
q = _y - Y

Q = A + (B - A) * p
R = C + (D - C) * p

P = R + (Q - R) * q
P = round(R + (Q - R) * q)

P_bytes = bytearray(P.to_bytes(4, 'big')) # 0x00aabbcc
P_bytes[0] = 0xff # 0xffaabbcc

return int.from_bytes(P_bytes, 'big')

return round(P)

11 changes: 8 additions & 3 deletions src/pycture/commands/edit_commands/scale.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from PyQt5.QtWidgets import QWidget, QMainWindow
from ..command import Command
from .interpolation import nearest_neighbor_interpolation
from .interpolation import bilinear_interpolation, nearest_neighbor_interpolation
from pycture.dialogs import ScaleDialog
from pycture.editor import Editor

Expand All @@ -10,13 +10,14 @@ def __init__(self, parent: QWidget):
super().__init__(parent, "Scale")
self.interpolation_techniques = {
"Nearest neighbour": nearest_neighbor_interpolation,
"Bilinear": bilinear_interpolation,
}

def execute(self, main_window: QMainWindow):
# Open dialog
# Connect dialog button to rotate function
self.main_window = main_window
dialog = ScaleDialog(main_window, main_window.get_editor_list())
dialog = ScaleDialog(main_window, main_window.get_editor_list(), list(self.interpolation_techniques.keys()))
dialog.set_editor(main_window.get_active_editor_name())
dialog.set_interpolation_technique(
list(self.interpolation_techniques.keys())[0])
Expand All @@ -26,7 +27,11 @@ def execute(self, main_window: QMainWindow):
def apply_scale(self,
editor_title: str, interpolation_name: str, new_size: (int, int)
):
image, title = self.get_active_image_and_title(self.main_window)
editor = self.main_window.get_editor(editor_title)
image = editor.get_image()
title = editor.windowTitle()


interpolation_technique = self.interpolation_techniques[interpolation_name]
scaled_image = image.scale(new_size, interpolation_technique)
self.main_window.add_editor(editor=Editor(
Expand Down
8 changes: 4 additions & 4 deletions src/pycture/dialogs/scale_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ class ScaleDialog(QDialog):
# img interpolation size(int, int)
applied = Signal(str, str, tuple)

def __init__(self, parent: QMainWindow, editors: List[str]):
def __init__(self, parent: QMainWindow, editors: List[str], interpolation_techniques: List[str]):
super().__init__(parent, Qt.WindowType.Window)
self.setWindowTitle("Scale")
self.layout = QVBoxLayout()
self.layout.setSizeConstraint(QLayout.SetFixedSize)
self.setLayout(self.layout)
self.setup(editors)
self.setup(editors, interpolation_techniques)
self.show()

def setup(self, editors: List[str]):
def setup(self, editors: List[str], interpolation_techniques: List[str]):
layout = QVBoxLayout()
self.layout.addLayout(layout)

self.editors_dropdown = DropdownList(self, editors)
layout.addWidget(self.editors_dropdown)

self.interpolation_dropdown = DropdownList(self, ["Nearest neighbour"])
self.interpolation_dropdown = DropdownList(self, interpolation_techniques)
layout.addWidget(self.interpolation_dropdown)

self.width = QLineEdit("1", self)
Expand Down