Hallo Forum,
Ich habe folgendes Problem. Es sind 2 Bilder vorhanden, welche einen Prägeprozess von Karton im Querschnitt darstellen.
Bild1: https://picload.org/view/dcllirdp/v1_01_01.png.html
Bild2: https://picload.org/view/dcllirdw/v1_01_02.png.html
Im ersten Bild ist der Karton noch geradlinig. Im zweiten Bild sinusförmig, da er geprägt wurde.
Der Karton ist in den Bildern lila dargestellt.
Grundsätzlich soll die Verschiebung des Materials herausgefunden/dargestellt werden.
Meine Idee ist dazu markante Punkte (stark lila gefärbte Punkte) zu vergleichen. Also theoretisch dürfte es mehrere Punkte im lila gefärbten Bereich geben, welche identisch sind. Diese Pixel sollten besser kenntlich gemacht werden und in eine definierte Farbe gefärbt werden.
Zur besseren Verständnis habe ich dies manuell mit Photoshop getan.
Bild1: https://picload.org/view/dcllirdr/v1.jpg.html
Bild2: https://picload.org/view/dcllirdd/v2.jpg.html
Meine erste Frage ist, geht das auch automatisch, solche Punkte zu erkennen und einzufärben mit Python?
Eventuell müssten die Punkte auch benannt oder definiert werden.
Wenn das erfolgt ist, würde ich gerne die Bilder voneinander subtrahieren oder vergleichen, sodass dann jeweils die zusammengehörigen Punkte verbunden werden und der Vektor dann die Verschiebung darstellt.
Ich habe leider sehr wenig Erfahrung mit Programmierung, vor allem mit Python. Ich bin froh wenn ich die Bilder reinladen und anzeigen kann
Deshalb wäre meine generelle Frage, ob meine Ideen so umsetzbar sind in Python und ob jemand eventuell Codebefehle kennt für die automatische Pixelerkennung oder die Vektorenerstellung zwischen den Punkten der 2 Bilder.
Ich bin für jede Hilfe und jeden Rat dankbar!
Gruß Cyber
Bildervergleich / Pixelerfassung
Die Bibliothek die du dazu benutzen willst nennt sich "OpenCV", und ist fuer Python verfuegbar. Damit hast du einen ganzen Sack von Funktionen, mit denen du dein Problem bearbeiten kannst:
- Transformation in den HSV-Raum, um nach Farbe zu segmentieren.
- Tools zur Ecken-Erkennung, um Bildanteile an Kanten zu segmentieren.
- Morphologische Operationen, um diese Anteile sauber zu machen.
- Dinge wie Hough-Lines, linear fits, contour extraction und polygon-annaeherung, mit denen du dir ein Aehnlichkeitsmass bauen kannst.
Das ganze setzt aber durchaus eine ganze Menge an Programmier- und Computer-Vision-Erfahrung vorraus, wenn man das robust hinkriegen will.
Eine Alternative sind natuerlich ggf. auch maschinelle Lernverfahren, allerdings muss man dafuer auch ausreichend Trainingsdaten haben.
- Transformation in den HSV-Raum, um nach Farbe zu segmentieren.
- Tools zur Ecken-Erkennung, um Bildanteile an Kanten zu segmentieren.
- Morphologische Operationen, um diese Anteile sauber zu machen.
- Dinge wie Hough-Lines, linear fits, contour extraction und polygon-annaeherung, mit denen du dir ein Aehnlichkeitsmass bauen kannst.
Das ganze setzt aber durchaus eine ganze Menge an Programmier- und Computer-Vision-Erfahrung vorraus, wenn man das robust hinkriegen will.
Eine Alternative sind natuerlich ggf. auch maschinelle Lernverfahren, allerdings muss man dafuer auch ausreichend Trainingsdaten haben.
Weil ich lange nix mehr mit opencv gemacht habe - hier ein Stueck Code, welches eine korrekte Klassifikation fuer deine beiden Testbilder abliefert:
Laufen gelassen unter Ubuntu 18.04 python 3.6 und dem dafuer verfuegbaren OpenCV 3.
Code: Alles auswählen
import sys
from functools import wraps, partial
from collections import namedtuple, deque
import cv2
import numpy as np
Settings = namedtuple(
"Settings",
"Hhigh Hlow Slow Shigh Vlow Vhigh kernel_size"
)
# through clicking determined
S = 60
S_ADJUST = 20
V = 220
V_ADJUST = 20
DEFAULT_SETTINGS = Settings(
Hhigh=130,
Hlow=124,
Shigh=S + S_ADJUST,
Slow=S - S_ADJUST,
Vhigh=V + V_ADJUST,
Vlow=V - V_ADJUST,
kernel_size=20,
)
def memoize(f):
@wraps(f)
def _d(*a, **k):
key = a, tuple((key, value) for key, value in k.items())
if key not in f._cache:
f._cache[key] = f(*a, **k)
return f._cache[key]
f._cache = {}
return _d
def create_hsv_preview(img):
"""
Takes an HSV-image, and returns
a copy where the SV components
are maxed out, in BGR-colorspace.
This allows to perceive the way sectioning
in H-space works.
"""
hsv_preview = img.copy()
hsv_preview[:, :, 1:] = [255, 255]
return cv2.cvtColor(hsv_preview, cv2.COLOR_HSV2BGR)
def filter_for_color_range(roi, s):
lower = range_array(s.Hlow, s.Slow, s.Vlow)
upper = range_array(s.Hhigh, s.Shigh, s.Vhigh)
return cv2.inRange(roi, lower, upper)
@memoize
def range_array(*a):
return np.array(a, dtype="uint8")
def mouse_callback(queue, event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
queue.append((x, y))
def setup_mouse_callback(q):
cv2.namedWindow("original")
cv2.setMouseCallback("original", partial(mouse_callback, q))
def morph(image, size=5):
kernel = np.ones((size, size), np.uint8)
a = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
return cv2.morphologyEx(a, cv2.MORPH_OPEN, kernel)
def main():
image = cv2.imread(sys.argv[1])
clicks = deque()
setup_mouse_callback(clicks)
cv2.imshow("original", image)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", create_hsv_preview(hsv))
filtered = filter_for_color_range(
hsv,
DEFAULT_SETTINGS,
)
cv2.imshow("filtered", filtered)
morphed = morph(filtered, DEFAULT_SETTINGS.kernel_size)
cv2.imshow("morphed", morphed)
_, contours, _ = cv2.findContours(
morphed,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE,
)
assert len(contours) == 1
contour = image.copy()
epsilon = 0.001 * cv2.arcLength(contours[0], True)
approx = cv2.approxPolyDP(contours[0], epsilon, True)
print(len(approx))
cv2.drawContours(contour, contours, 0, (255, 255, 0))
cv2.drawContours(contour, [approx], 0, (0, 255, 255))
cv2.imshow("contour", contour)
print("gebogen" if len(approx) > 20 else "gerade")
while True:
key = cv2.waitKey(10)
if key == 27:
break
for x, y in clicks:
print(hsv[y,x,:])
clicks.clear()
if __name__ == '__main__':
main()
-
- User
- Beiträge: 2
- Registriert: Montag 3. Dezember 2018, 13:18
Super das hilft mir auf jeden Fall schon mal weiter.
Danke!
Danke!
-
- User
- Beiträge: 3
- Registriert: Samstag 29. Dezember 2018, 12:16
Servus deets,
ich habe jetzt längers versucht diesen Code iwie zum laufen zu kriegen aber bei funktioniert es einfach nicht. Ich bin ebenfalls aus der Projektgruppe, die dieses Projekt bearbeitet...also genauso ein Nichtkönner
Muss ich irgendwas beachten wenn ich mir den Code rauskopiere? Iwas umstellen? Wo die Bilder anlegen, einlesen?
Entschuldige falls dies doofe Fragen sind Kann das auch an Ubuntu/Windows liegen?
Liebe Grüße Path
ich habe jetzt längers versucht diesen Code iwie zum laufen zu kriegen aber bei funktioniert es einfach nicht. Ich bin ebenfalls aus der Projektgruppe, die dieses Projekt bearbeitet...also genauso ein Nichtkönner
Muss ich irgendwas beachten wenn ich mir den Code rauskopiere? Iwas umstellen? Wo die Bilder anlegen, einlesen?
Entschuldige falls dies doofe Fragen sind Kann das auch an Ubuntu/Windows liegen?
Liebe Grüße Path
__deets__ hat geschrieben: ↑Montag 3. Dezember 2018, 18:41 Weil ich lange nix mehr mit opencv gemacht habe - hier ein Stueck Code, welches eine korrekte Klassifikation fuer deine beiden Testbilder abliefert:
Laufen gelassen unter Ubuntu 18.04 python 3.6 und dem dafuer verfuegbaren OpenCV 3.Code: Alles auswählen
import sys from functools import wraps, partial from collections import namedtuple, deque import cv2 import numpy as np Settings = namedtuple( "Settings", "Hhigh Hlow Slow Shigh Vlow Vhigh kernel_size" ) # through clicking determined S = 60 S_ADJUST = 20 V = 220 V_ADJUST = 20 DEFAULT_SETTINGS = Settings( Hhigh=130, Hlow=124, Shigh=S + S_ADJUST, Slow=S - S_ADJUST, Vhigh=V + V_ADJUST, Vlow=V - V_ADJUST, kernel_size=20, ) def memoize(f): @wraps(f) def _d(*a, **k): key = a, tuple((key, value) for key, value in k.items()) if key not in f._cache: f._cache[key] = f(*a, **k) return f._cache[key] f._cache = {} return _d def create_hsv_preview(img): """ Takes an HSV-image, and returns a copy where the SV components are maxed out, in BGR-colorspace. This allows to perceive the way sectioning in H-space works. """ hsv_preview = img.copy() hsv_preview[:, :, 1:] = [255, 255] return cv2.cvtColor(hsv_preview, cv2.COLOR_HSV2BGR) def filter_for_color_range(roi, s): lower = range_array(s.Hlow, s.Slow, s.Vlow) upper = range_array(s.Hhigh, s.Shigh, s.Vhigh) return cv2.inRange(roi, lower, upper) @memoize def range_array(*a): return np.array(a, dtype="uint8") def mouse_callback(queue, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: queue.append((x, y)) def setup_mouse_callback(q): cv2.namedWindow("original") cv2.setMouseCallback("original", partial(mouse_callback, q)) def morph(image, size=5): kernel = np.ones((size, size), np.uint8) a = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel) return cv2.morphologyEx(a, cv2.MORPH_OPEN, kernel) def main(): image = cv2.imread(sys.argv[1]) clicks = deque() setup_mouse_callback(clicks) cv2.imshow("original", image) hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) cv2.imshow("hsv", create_hsv_preview(hsv)) filtered = filter_for_color_range( hsv, DEFAULT_SETTINGS, ) cv2.imshow("filtered", filtered) morphed = morph(filtered, DEFAULT_SETTINGS.kernel_size) cv2.imshow("morphed", morphed) _, contours, _ = cv2.findContours( morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE, ) assert len(contours) == 1 contour = image.copy() epsilon = 0.001 * cv2.arcLength(contours[0], True) approx = cv2.approxPolyDP(contours[0], epsilon, True) print(len(approx)) cv2.drawContours(contour, contours, 0, (255, 255, 0)) cv2.drawContours(contour, [approx], 0, (0, 255, 255)) cv2.imshow("contour", contour) print("gebogen" if len(approx) > 20 else "gerade") while True: key = cv2.waitKey(10) if key == 27: break for x, y in clicks: print(hsv[y,x,:]) clicks.clear() if __name__ == '__main__': main()
"Geht nicht" ist keine sinnvolle Fehlerbeschreibung. Was passiert, wenn du das Skript aufrufst? Gibt es eine Fehlermeldung, wenn ja, wie genau lautet die? Bitte VOLLSTAENDIG reinkopieren, und nicht paraphrasieren.
Und das Skript muss mit dem Bild als Argument aufgerufen werden.
Und das Skript muss mit dem Bild als Argument aufgerufen werden.
-
- User
- Beiträge: 3
- Registriert: Samstag 29. Dezember 2018, 12:16
Tschuldige! Mein Fehler, vergessen reinzukopieren.__deets__ hat geschrieben: ↑Samstag 29. Dezember 2018, 13:24 "Geht nicht" ist keine sinnvolle Fehlerbeschreibung. Was passiert, wenn du das Skript aufrufst? Gibt es eine Fehlermeldung, wenn ja, wie genau lautet die? Bitte VOLLSTAENDIG reinkopieren, und nicht paraphrasieren.
Und das Skript muss mit dem Bild als Argument aufgerufen werden.
Also hier wie ich deinen Code ausführe:
Code: Alles auswählen
import sys
from functools import wraps, partial
from collections import namedtuple, deque
import cv2
import numpy as np
img = cv2.imread('V1_01_01.png')
#img = cv2.imread('V1_01_02.png')
Settings = namedtuple("Settings", "Hhigh Hlow Slow Shigh Vlow Vhigh kernel_size")
# through clicking determined
S = 60
S_ADJUST = 20
V = 220
V_ADJUST = 20
DEFAULT_SETTINGS = Settings(Hhigh=130, Hlow=124, Shigh=S+S_ADJUST, Slow=S-S_ADJUST, Vhigh=V+V_ADJUST, Vlow=V-V_ADJUST, kernel_size=20)
def memoize(f):
@wraps(f)
def _d(*a, **k):
key = a, tuple((key, value) for key, value in k.items())
if key not in f._cache:
f._cache[key] = f(*a, **k)
return f._cache[key]
f._cache = {}
return _d
def create_hsv_preview(img):
"""
Takes an HSV-image, and returns
a copy where the SV components
are maxed out, in BGR-colorspace.
This allows to perceive the way sectioning
in H-space works.
"""
hsv_preview = img.copy()
hsv_preview[:, :, 1:] = [255, 255]
return cv2.cvtColor(hsv_preview, cv2.COLOR_HSV2BGR)
def filter_for_color_range(roi, s):
lower = range_array(s.Hlow, s.Slow, s.Vlow)
upper = range_array(s.Hhigh, s.Shigh, s.Vhigh)
return cv2.inRange(roi, lower, upper)
@memoize
def range_array(*a):
return np.array(a, dtype="uint8")
def mouse_callback(queue, event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
queue.append((x, y))
def setup_mouse_callback(q):
cv2.namedWindow("original")
cv2.setMouseCallback("original", partial(mouse_callback, q))
def morph(image, size=5):
kernel = np.ones((size, size), np.uint8)
a = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
return cv2.morphologyEx(a, cv2.MORPH_OPEN, kernel)
def main():
image = cv2.imread(sys.argv[1])
clicks = deque()
setup_mouse_callback(clicks)
cv2.imshow("original", image)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", create_hsv_preview(hsv))
filtered = filter_for_color_range(
hsv,
DEFAULT_SETTINGS,
)
cv2.imshow("filtered", filtered)
morphed = morph(filtered, DEFAULT_SETTINGS.kernel_size)
cv2.imshow("morphed", morphed)
_, contours, _ = cv2.findContours(
morphed,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE,
)
assert len(contours) == 1
contour = image.copy()
epsilon = 0.001 * cv2.arcLength(contours[0], True)
approx = cv2.approxPolyDP(contours[0], epsilon, True)
print(len(approx))
cv2.drawContours(contour, contours, 0, (255, 255, 0))
cv2.drawContours(contour, [approx], 0, (0, 255, 255))
cv2.imshow("contour", contour)
print("gebogen" if len(approx) > 20 else "gerade")
while True:
key = cv2.waitKey(10)
if key == 27:
break
for x, y in clicks:
print(hsv[y,x,:])
clicks.clear()
if __name__ == '__main__':
main()
Anschließend kommt folgende Fehlermeldung. Wiegesagt entschuldige, bin völliger Anfänger und versuche iwie zurecht zu kommen
Code: Alles auswählen
runfile('C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum/SkriptForum.py', wdir='C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum')
Traceback (most recent call last):
File "<ipython-input-1-dc236a07e07b>", line 1, in <module>
runfile('C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum/SkriptForum.py', wdir='C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum')
File "C:\Users\kh94\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 668, in runfile
execfile(filename, namespace)
File "C:\Users\kh94\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum/SkriptForum.py", line 126, in <module>
main()
File "C:/Users/kh94/Documents/HTWK_DVM/HTWK_2_Semester/Mustererkennung/Tests/Test_8_SkriptForum/SkriptForum.py", line 85, in main
image = cv2.imread(sys.argv[1])
IndexError: list index out of range
__deets__ hat geschrieben: Und das Skript muss mit dem Bild als Argument aufgerufen werden.
Hast Du aber nicht gemacht. Dafür lädst Du am Anfang ein Bild als `img`, das aber nie verwendet wird und an der Stelle auch gar nicht stehen sollte.
Hast Du aber nicht gemacht. Dafür lädst Du am Anfang ein Bild als `img`, das aber nie verwendet wird und an der Stelle auch gar nicht stehen sollte.
-
- User
- Beiträge: 3
- Registriert: Samstag 29. Dezember 2018, 12:16
Hei,
sorry aber wir studieren leider alle Verpackungstechnik und sollen hier iwas programmieren...(sehr sinnvoll ich weiß).
Wie rufe ich das Skript mit dem Bild als Argument auf?
Im Skript also nichts mehr ändern und es zusammen über die cmd ausführen oder verstehe ich das wieder falsch?
So habe ich es zumindest in anderen Fällen schon gesehen.
Danke dir vielmals im voraus!
sorry aber wir studieren leider alle Verpackungstechnik und sollen hier iwas programmieren...(sehr sinnvoll ich weiß).
Wie rufe ich das Skript mit dem Bild als Argument auf?
Im Skript also nichts mehr ändern und es zusammen über die cmd ausführen oder verstehe ich das wieder falsch?
So habe ich es zumindest in anderen Fällen schon gesehen.
Danke dir vielmals im voraus!
Das funktioniert doch niemals. Das Skript ist doch nur eine Ideenskizze. Bis da die geforderte Aufgabe (so wie zumindest beschrieben im ersten Post) bei rum kommt, ist noch eine Menge zu tun. Wer denkt sich denn eine solche Nummer aus?
Und ja: nichts ändern. “Python Skript.py Bild.png” (ohne Anführungszeichen!) in der Eingabeaufforderung eingeben. Die Pfade zu den drei Bestandteilen müssen natürlich passen.
Und ja: nichts ändern. “Python Skript.py Bild.png” (ohne Anführungszeichen!) in der Eingabeaufforderung eingeben. Die Pfade zu den drei Bestandteilen müssen natürlich passen.