lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · ha -1-et értéket...

15

Upload: others

Post on 16-Jul-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági
Page 2: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Lényege: valamilyen szempont szerint homogén csoportok képzése a pixelekből.

Amit már ismerünk:

◦ Küszöbölés, vágás, sávkijelölés

◦ hátránya: az azonos csoportba sorolt pixelek nem feltétlenül alkotnak összefüggő halmazt.

Page 3: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Tekintsük a képet egy domborzati térképként.

Page 4: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Képzeljük el, hogy a (környezettől erősen eltérő) lokális minimumhelyeknél feltört a víz.

Az üregek folyamatosan töltődnek fel vízzel. Ahol a különböző forrásokból származó víz összefolyna, ott gátat képzünk (szegmensek határai).

Page 5: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Töltsd le a sejteket tartalmazó képet, és olvasd be színesben. https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/sejtek.bmp

Állíts elő két maszkot, az egyiken a sötétlila, a másikon a sötétbarna sejtek legyenek ◦ sötétbarna HSV tartomány: (0, 10, 0) -tól (30, 255, 150) -ig

◦ sötétlila HSV tartomány : (80, 10, 0) -tól (170, 255, 150) -ig

◦ (javasolt a cvtConvert és az inRange használta)

Hozz létre egy képet a markereknek (a "feltörő források") ◦ A kép típusa: CV_32S, mérete az eredeti képével azonos

◦ Kezdetben minden pixel fekete.

◦ A sötétbarna pixeleket állítsd be 128-as értékre. (javasolt: marker.setTo( 128, barna_maszk) )

◦ A sötétlila pixeleket állítsd be 255-ös értékre. (Más pozitív érték is lehet, de ezek jól láthatóan eltérnek, ha megjeleníted a képet 255-tel szorozva.)

Hajtsd végre a watershed trf-et. ◦ watershed(színes_bemeneti_kep, marker_kep);

A marker képet convertált CV_8UC1-re vagy rajzold át a 128-as, ill. 255-ös értékű pontokat egy új képre és jelenítsd meg. (javasolt az első megoldás: marker_kep.convertTo( uj_kep, CV_8U, 1.0))

Page 6: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Töltsd le a következő képet és olvasd be színesben: https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/skate.jpg

Állítsd elő a lokális minimumhelyeket tartalmazó maszkot ◦ Alakíts szürkeskálássá a képet.

◦ Készíts egy s×s méretű, CV_8U típusú mátrixot, melynek minden pontja 1, kivéve a középpontja, mely 0. ( s értéke szabályozza a lokális mininum helyek közti távolságot, kb. 5, 7)

◦ Erodáld a képet a mátrixszal: erode( a_szurkeskalas_kep, a_cel_kep, a_matrix);

◦ lokalis_minimum = a_szurkeskalas_kep < a_cel_kep; //megj: homogén részre nem reagál

Hozz létre egy képet a markereknek (a "feltörő források") ◦ A kép típusa: CV_32S, mérete az eredeti képével azonos

◦ Kezdetben minden pixel fekete.

◦ Az összes lokális minimum értéket állítsd egynél nagyobb, egymástól különböző értékre.

(pl. bejárod a lokalis_minimum képet, és ha találsz egy előtérpontot, akkor növelsz egy nulláról induló számlálót. A növelt számláló értékét állítod be a markerkép adott pontjában értéknek.

Hajtsd végre a watershed trf-et. ◦ watershed(színes_bemeneti_kep, marker_kep);

Page 7: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Hozz létre egy szegmens struktúrát / osztályt struct Segment{

vector<cv::Point> pts;

float feature; //lehet több is

int idx; //egy szegmens indexe };

Készíts függvényt, mely összegyűjti a watershed trf. eredményképe alapján a szegmenseket. ◦ A numLabel a lokális minimumhelyek száma (watershed trf-nél meghatároztad)

void collectSegments(cv::Mat_<int> markers, vector<Segment>& segments, int numLabel){

A segments vektor méretezd át numLabel-re.

Járd be a markerképet

m jelölje az aktuális pont markerkép értékét

Ha m eleme a [0, numLabel-1] tartománynak akkor

a segmens vektor m. eleméhez add hozzá az aktuális pontot

//segments[m].push_back( Point(aktualis_pont_koordinatai) );

}

Page 8: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Készíts függvényt, mely beállítja az előbb begyűjtött szegmensek jellemzőit

A numLabel a lokális minimumhelyek száma (watershed trf-nél meghatároztad, ismered)

Ha rgb képet akarsz majd átadni, akkor az img-t alakítsd szürkeskálásra ◦ cvtConvert( img, gray, COLOR_BGR2GRAY );

void setSegmentsFeatures(const cv::Mat img, vector<Segment>& segments) {

//járd be a szegmens vektort (sima for ciklus)

az aktuális szegmes tulajdonságait állítsd be:

idx értéke legyen a vektorban elfoglalt helye (ciklusváltozó)

feature értéke legyen a szegmens pontjainak átlagos szürkeségi értéke

a pts vektor pontjai és az img alapján meghatározhatod

}

Page 9: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Készíts függvényt, mely meghatározza a hasonló szegmenseket. ◦ (ez a fajta megoldás az egymástól távol álló szegmenseket is hasonlónak tudja tekinteni)

Az eredmény egy hasonlósági mátrix. 1-es áll egy mezőben, ha az adott sornak megfelelő indexű szegmens hasonlít az adott oszlopban álló szegmensre.

A tárolás a felső háromszögben történjen (vagy legyen szimmetrikus)

void segmentsForMerge(vector<Segment>& segments, cv::Mat& mergeMat, int threshold) {

Hozd létre csupa nullával feltöltve a hasonlósági mátrixot (mergeMat)

mérete a segmensek számával azonos

Járd be a szegmenseket ( i = 0; … )

Járd be az i-től nagyobb sorszámú szegmenseket ( j = i+1; … )

Ha a két szegmens feature értékének eltérése a megadott

küszöbérték (threshold) alatt van, akkor

a mátrix (i, j). eleme legyen 1-es értékű.

}

Page 10: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Ha szeretnéd, hogy egymástól távoli szegmensek ne kapcsolódhassanak közvetlenül, akkor a marker képen távolítsd el a határoló vonalakat

void dilateMarkers(cv::Mat_<int>& markers){

Járd be a mátrixot

Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával.

}

Hozz létre egy szomszédsági mátrixot (szimmetrikus / felső háromszög), ez alapján lehet majd törölni az előző mergeMat-ból a nem kívánt elemeket.

void neigbourSegments(Mat_<int> markers, cv::Mat& neigbourMat, int numSeg) {

neigbourMat = Mat::zeros(cv::Size(numSeg, numSeg), CV_8UC1);

//járd be a marker képet (vigyázz, hogy majd a szomszéd is beférjen a tartományba)

//A marker értékek a szegmensek indexével azonosak a korábbi feltöltés miatt

jelölje s1 az (i, j) és s2 a (i, j+1) pont markerét

Ha egyik sem -1, akkor jelöld a s1. és s2. szegmenst szomszédosnak*

neigbourMat.at<uchar>(s1, s2) = neigbourMat.at<uchar>(s2, s1) = 1;

Ugyanezeket a lépéseket tedd meg a (i, j) és (i+1, j) pontokra is.

}

*(a dilateMarkers-nél választott szomszédoktól függően maradhat-1-es érték) akkor

Page 11: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Szegmens összeolvasztás, ha a pontosorzatokkal nem foglalkozunk void mergeSegments(vector<Segment>& segments, cv::Mat_<uchar> mergeMat) {

Járd be a mergeMat mátrix FELSŐ háromszög részét (

for( i = 0; … )

for (j = i+1 …)

ha a mergeMat aktuális eleme nem nulla, akkor a j. szegmens indexét

állítsd át az i. szegmens indexére.

Szegmens összeolvasztás, ha a szegmensek pontjait is meg akarjuk kapni void mergeSegments(vector<Segment>& segments, cv::Mat_<uchar> mergeMat) {

//ilyenkor visszafelé haladunk (hogy a már összevontat vonjuk később össze)

for (int i = mergeMat.rows-1; i >=0; --i) {

for (int j = mergeMat.cols - 1; j >= i + 1; --j) {

ha a mergeMat aktuális eleme nem nulla, akkor

az i. szegmens pontjaihoz (pts) add hozzá a j. szegmens pontjait.

//segments[i].insert(…))

majd töröld a j. szegmensből a pontokat

//segments[j].cleare();

Page 12: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Az alábbi függvény kirajzolja a szegmenseket void drawSegment(cv::InputOutputArray dest, const vector<Segment>& segments) {

vector<cv::Vec3b> lookUp( segments.size());

for (int i = 0; i < segments.size(); ++i)

lookUp[i] = cv::Vec3b(rand() % 250 + 50, rand() % 255, rand() % 255);

cv::Mat& destMat = dest.getMatRef();

for (auto s : segments) {

if (s.pts.size() > 0) {

cv::Vec3b color = lookUp[s.idx];

for (auto p : s.pts)

destMat.at<cv::Vec3b>(p) = color;

}

}

Page 13: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

És végül a függvény, ami az egészet összefogja: void hierSegment(const Mat_<cv::Vec3b> img, Mat_<int> markers, Mat& dest, int numSeg, float

threshold = 20.0, bool mergeOnlyNeighbour = false) {

//körvonalak eltávolítása a marker képről (mergeOnlyNeighbour igaz értékénél fontos)

dilateMarkers(markers);

vector<Segment> segments;

collectSegments( markers, segments, numSeg);

setSegmentsFeatures(img, segments);

cv::Mat mergeMat;

segmentsForMerge(segments, mergeMat, threshold);

if (mergeOnlyNeighbours) { //csak ha megcsináltad

cv::Mat neighbourMat;

neigbourSegments(markers, neighbourMat, numSeg);

mergeMat &= neighbourMat;

}

mergeSegments(segments, mergeMat);

dest.create(markers.size(), CV_8UC3);

drawSegment(dest, segments);

}

Page 14: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági

Watershed (beépített) (gauss 3x3, sigma=2)

markerek a lokális maximumhelyek (5x5)

Hasonló szegmensek összevonása összevonás küszöbértéke 15 jellemző: átlagos intenzitás

Hasonló, 4-szomszédság szerint

kapcsolódó szegmensek összevonása után

Eredeti

Page 15: Lényege: valamilyen szempont szerint homogén csoportok … · 2017-04-26 · Ha -1-et értéket találsz, írd felül egy nem -1 értékű szomszédjával. } Hozz létre egy szomszédsági