Znalezienie linii, współrzędnych ich końca i przekazanie na drugi obraz

4

Witam,
w ramach projektu na studiach tworzymy grę PaperSoccer z użyciem OpenCV.

Oryginalna plansza do gry wygląda tak:

1.jpg

A zdjęcie ze zrobionym jednym ruchem wygląda tak:

2.jpg

Używamy funkcji, które usuwają perspektywę na zdjęciu z ruchem i jesteśmy w stanie znaleźć współrzędne punktów, po których będziemy się poruszać tj. kropek. SOURCE CODE

Chcemy znaleźć miejsce w którym został wykonany ruch i przenieść go na planszę oryginalną.Próbowaliśmy użyć funkcji > absdiff(img1,img2,result)
aby znaleźć różnicę między zdjęciem planszy oryginalnej a pierwszym ruchem, następnie ruchem pierwszym a drugim itd, a następnie użyć funkcji wykrywającej i rysującej linie w miejscu w którym została znaleziona.

int DetectLines(Mat src, const char* sourceName, const char* destName){

Mat dst, cdst;
Mat zapisz;
zapisz = imread("plansza3.jpg",0);

Canny(src, dst, 50, 200, 3);
cvtColor(dst, cdst, COLOR_GRAY2BGR);

vector<Vec4i> lines;

HoughLinesP(dst, lines, 1, CV_PI / 180, 20, 10, 5);

for (size_t i = 0; i < 1; i++)
{
    Vec4i l = lines[i];
    line(zapisz, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, 2);
}

imshow(destName, zapisz);

return 0;
}

Jednak nie działą to poprawnie.
Tak naprawdę potrzebne nam są współrzędne znalezionej linii, aby przekazać je do logiki gry. Jednak nie wiemy jak zrobić, aby punkty z naszej planszy ze zdjęcia odpowiadały punktom planszy oryginalnej i aby za każdym razem wykrywało tylko nowy ruch, a nie wszystkie poprzednie.

0

Można kilka operacji zastosować na obrazie, np. filtr kolorów, nie potrzebne są czarne linie.

Potem, można np. dylatację zastosować, żeby polepszyć widoczność tych linii, jakieś rozmycie gaussowskie.
Można też trochę pokombinować z różnymi parametrami transformacji hougha.

W efekcie otrzymamy kilka linii, gdyż zwykle są blisko siebie, o kilka pixeli różnicy, leczy jeśli np. będziesz graf z tego tworzyć.
To i tak między wierzchołkami może być tylko jedno połączenie, lecz także można ilość tych linii zredukować, gdyż różnią się niewielką wartością rzędu kilku pixelu, czyli można uznać jako jedną linię.

Przy dobraniu lepszych parametrów też można lepsze efekty uzyskać.

Tutaj jakiś prototyp, który działa na przykładzie.

import cv2
import numpy as np

org_image = cv2.imread("linesss.jpg")
image = np.copy(org_image)

lower_red = np.array([147, 30, 145])
upper_red = np.array([255, 255, 255])

hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_red, upper_red)

blur = cv2.GaussianBlur(mask, (5, 5), 1)

lines = cv2.HoughLinesP(blur, 1, np.pi/180, 100, minLineLength=100, maxLineGap=30)

if lines is not None:
    print(len(lines))
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(image, (x1,y1), (x2, y2), color=(0,255,0), thickness=2)

image_org = cv2.resize(org_image, (800,600))
image = cv2.resize(image, (800,600))
edge = cv2.resize(blur, (800,600))

cv2.imshow("org", image_org)
cv2.imshow("edge", edge)
cv2.imshow("test", image)

cv2.waitKey()
cv2.destroyAllWindows()

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0