package wektoryzacja; import java.io.File; import java.util.ArrayList; import java.util.List; import pl.wroc.pwr.image.IRGBImage; import pl.wroc.pwr.image.io.GenericLoader; import pl.wroc.pwr.image.io.GenericSaver; import pl.wroc.pwr.image.model.RGBImage; import pl.wroc.pwr.imagechannel.IImageChannel; import pl.wroc.pwr.imagechannel.basic.Invert; import pl.wroc.pwr.imagechannel.draw.DrawX; import pl.wroc.pwr.imagechannel.model.ImageChannel; import pl.wroc.pwr.roi.IROI; import pl.wroc.pwr.roi.basic.ROIFromThreshold; public class WektoryzacjaKrzywej { private SzeregowaniePunktow szeregowanie = new SzeregowaniePunktow(); private double epsilon; public WektoryzacjaKrzywej(double epsilon) { this.epsilon = epsilon; } private List naPunkty(List indeksy, List szereg) { List l = new ArrayList(); for (Integer indeks : indeksy) { l.add(szereg.get(indeks)); } return l; } private float dlugosc(List punkty) { float odl = 0; for (int i = 0; i < punkty.size() - 1; i++) { int[] aktualny = punkty.get(i); int[] nastepny = punkty.get(i + 1); int dx = aktualny[0] - nastepny[0]; int dy = aktualny[1] - nastepny[1]; float d = (float)Math.sqrt(dx * dx + dy * dy); odl += d; } return odl; } public List wektoryzuj(IROI krzywaROI, IImageChannel kanal) { List szereg = this.szeregowanie.szeregujPunkty(krzywaROI, kanal); if (szereg == null) { return new ArrayList(); } List indeksy = new ArrayList(); indeksy.add(0); indeksy.add(szereg.size() - 1); boolean process = true; do { float najdluzsza = this.dlugosc(naPunkty(indeksy, szereg)); float staraNajdluzsza = najdluzsza; List nIndeksy = null; for (int i = 0; i < szereg.size(); i++) { List noweIndeksy = new ArrayList(); boolean dodany = false; for (Integer indeks : indeksy) { if ((i < indeks)&&(!dodany)) { noweIndeksy.add(i); dodany = true; } noweIndeksy.add(indeks); } float nowaDlugosc = this.dlugosc(naPunkty(noweIndeksy, szereg)); if (nowaDlugosc > najdluzsza) { najdluzsza = nowaDlugosc; nIndeksy = noweIndeksy; } } if (najdluzsza - staraNajdluzsza > this.epsilon) { //if (staraNajdluzsza * this.epsilon > najdluzsza) { indeksy = nIndeksy; } else { process = false; } } while (process); List punkty = this.naPunkty(indeksy, szereg); return punkty; } public void narysuj(IImageChannel kanal, List punkty, File plik) { IImageChannel drawChannel = new ImageChannel(kanal.getSize()); for (int[] coord : punkty) { new DrawX(drawChannel, coord[0], coord[1], 5, 1f).apply(); } IRGBImage out = new RGBImage(kanal, kanal, drawChannel); String nazwa = "output-" + plik.getName(); File wyjscie = new File(plik.getParent(), nazwa); new GenericSaver(out, wyjscie).apply(); } public static void main(String[] args) { File plik = new File("/home/mariusz/dane/nekst/krzywe/krzywa1.png"); IRGBImage image = new GenericLoader(plik).apply(); IImageChannel kanal = image.getBlueChannel(); kanal = new Invert(kanal).apply(); IROI roi = new ROIFromThreshold(0.5f).apply(kanal); WektoryzacjaKrzywej wektoryzacja = new WektoryzacjaKrzywej(1.01); List aproksymacja = wektoryzacja.wektoryzuj(roi, kanal); System.out.println("Lamana zawiera " + aproksymacja.size() + " punktow"); wektoryzacja.narysuj(kanal, aproksymacja, plik); } }