2016-05-12 11 views
6

Mam pomysł na projekt, ale udało mi się go zrealizować. Zasadniczo chciałbym użyć JavaScript do analizy obrazu (dowolnego obrazu), zabrać konkretny kolor i zmapować go na płótno HTML5 jako ścieżkę. Wszystkie analizowane obrazy będą podstawowymi kształtami o różnych kolorach. To jest przykład tego, co chciałbym zrobić.Wyodrębniaj obiekty o określonych kolorach i konwertuj na ścieżki.

enter image description here

Ten przykład jest to, co chciałbym skrypt do zrobienia, gdy zdał fioletowy odniesienie sześciokątną. Przekazanie go na niebiesko zmieniłoby wydruk na płótnie, aby pokazać tylko 2 niebieskie SHAPES. Czy ktoś ma jakieś pomysły na to, jak można to osiągnąć? bez użycia wtyczki? W niektórych miejscach płótno zostanie zmanipulowane, więc każdy kształt będzie musiał być oddzielną ścieżką (ponieważ nie zawsze będą to kształty 4-stronne).

+0

Dowolny obraz + Dowolny kolor + Dowolny kształt sprawia, że ​​pytanie jest zbyt szerokie. Ale i tak kilka myśli: "Kolor" na płótnie to RGBA, które trudno jest dopasować, jeśli cel ma nawet niewielkie odmiany kolorów RGBA. Możesz przekonwertować wszystkie wartości RGBA na HSL, a następnie wybrać kolor, który zapewnia większą tolerancję kolorów. "Kształt" jest niejednoznaczny, a pojedynczy kształt może być kombinacją wielu odłączonych części, ale można wykonać podstawowe wykrywanie krawędzi za pomocą [Marszowych kwadratów] (http://stackoverflow.com/questions/28207232/draw-border-round- nieprzezroczysty-część-obrazu-na-płótnie/28220510 # 28220510) Algorytm. – markE

Odpowiedz

0

Aby uzyskać komponenty kolor piksela o współrzędnych (x, y) z płótna, po prostu zrobić:

// assuming second canvas is same dimensions as first one 
var secondCanvasId = context.createImageData(canvas.width, canvas.height); 
for (var x = 0; x < canvas.width; x++) { 
    for (var y = 0; y < canvas.height; y++) { 
    var pix = context.getImageData(x, y, 1, 1).data; 
    var r = pix[0]; 
    var g = pix[1]; 
    var b = pix[2]; 
    var a = pix[3]; 
    // set canvas2 (x, y) pixel with this color, if it matches the choosen color 
    if (r === color.r && g === color.g && b === color.b && a === color.a) { 
     secondCanvasId.data[0] = r; 
     secondCanvasId.data[1] = g; 
     secondCanvasId.data[2] = b; 
     secondCanvasId.data[3] = a; 
     context.putImageData(secondCanvasId, x, y); 
    } 
    } 
} 
+0

Czy muszę znać wartości x, y bloku?Potrzebuję go, aby automatycznie wykryć wartości x, y kolorów. Coś takiego. 1. Skrypt analizuje każdy piksel na obrazie. 2. Jeśli kolor piksela jest równy podanemu kolorowi, wypisz go na kanwie jako kształt. –

+0

Tak, po prostu zamknij mój kod odpowiedzi w podwójnej pętli 'for', aby przeskanować wszystkie piksele w obszarze roboczym (zobacz moją zaktualizowaną odpowiedź ...). – MarcoS

+0

Dzięki, zrobię to teraz i dam ci znać, co się stanie :) –

1

Ponieważ pytanie jest dość szeroka, gdyż stoi nie dostarczy kod, ale ogólne podejście, w jaki sposób osiągnąć to.

Są to kroki, które należy podjąć:

Pierwsze przejście: zmniejszyć obraz na podstawie koloru i tolerancji. Jeśli kolor jest absolutny, po prostu wykonaj iterację i utwórz kanał alfa, w którym piksel nie pasuje do koloru. W przypadku tolerancji lepszym podejściem byłoby zastosowanie konwersji RGB-HSL, a następnie zdefiniowanie promienia i sprawdzenie, czy odczytany kolor znajduje się w promieniu w docelowym kolorze. Weź również pod uwagę wartości kanału alfa.

Zostanie wyświetlony obraz z kanałem alfa i tylko te kolory, które są po.

drugim przejściu: Run obraz przez roztwór przy użyciu kwadratów Marching algorytm (wtyczka bezwstydny: Zrobiłem własną here (licencja MIT) zainspirowany to pytanie, i to wydaje się być szybciej niż inni włącznie. wtyczkę D3 - ale każdy to zrobi!). Wyodrębnij ścieżki, wykonując iterację po obrazie, dla każdej iteracji usuń śledzoną część. Robisz to, głaszcząc + wypełniając uzyskaną ścieżkę, używając trybu kompozycji destination-out. Użyj szerokości linii około 3-5 specyficznej dla twojego scenariusza.

Możesz użyć Ramera-Douglasa-Peuckera, aby zmniejszyć punkty lub pozostawić je takimi, jakimi są. Brak redukcji punktu pozwoli uzyskać dokładną ścieżkę, ale będzie również gorszy.

Trzeci przebieg: Teraz masz dane ścieżki, które można wykorzystać do przycięcia części z oryginalnego obrazu. Dodaj wszystkie dane ścieżki (użyj ścieżek podrzędnych za pomocą metody moveTo() dla każdej ścieżki), a następnie tryb kompozycji, aby usunąć piksele, których nie chcesz. Lub, jeśli jesteście tylko po ścieżkach: gotowe!

+0

Stworzyłeś ładne Skrypt marszowy kwadratów. Brawo! – markE

Powiązane problemy