Обрада слика ОпенЦВ

Obrada Slika Opencv



У овом чланку ћемо проучити методе обраде слика. Испитаћемо неке фундаменталне, али критичне теме у компјутерској визији и машинском учењу. Ове основне технике обраде слике могу да реше сложене проблеме, као што су скупови података. Као резултат, постоји шест основних корака у обради слике, који су наведени у наставку:
  1. Превод слика
  2. Ротација слике
  3. Имаге Аритхметиц
  4. Имаге Флиппинг
  5. Имаге Цроппинг
  6. Промена величине слике

Сада ћемо детаљно објаснити све горе наведене теме обраде слика.

1. Превод слика

Превођење слике је метода обраде слике која нам помаже да померамо слику дуж к и и-осе. Можемо да померамо слику горе, доле, десно, лево или било коју комбинацију.







Можемо дефинисати транслациону матрицу са симболом М и можемо је представити у математичком облику, као што је приказано у наставку:





Кроз овај програм можемо разумети концепт преводилачке слике.





Питхон код: Име следећег програма задржаћемо као транслате.пи .

# потребног увоза пакета

увоз нумпи као што на пример.

увоз аргпарсе

увоз имутил

увоз цв2

# имплементирамо парсер аргумената

ап_обј = аргпарсе. АргументПарсер ( )

ап_обј. адд_аргумент ( '-к' , '--слика' , потребан = Истина ,

помоћ = 'локација датотеке слике' )

аргс = чији ( ап_обј. парсе_аргс ( ) )

# учитајте слику и прикажите на екрану

слика = цв2. имреад ( аргс [ 'слика' ] )

цв2. имсхов ( 'Оригинал_имаге' , слика )

# Превођење слике је НумПи матрица која је дата испод:

# [[1, 0, схифтКс], [0, 1, схифтИ]]

# Користићемо горњу НумПи матрицу да померимо слике дуж

# правци к-осе и и-осе. За ово морамо једноставно пренети вредности пиксела.

# У овом програму, слику ћемо померити за 30 пиксела удесно

# и 70 пиксела према дну.

превод_мат = на пример. флоат32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

имаге_транслатион = цв2. варпАффине ( слика , превод_мат ,

( слика. облик [ 1 ] , слика. облик [ 0 ] ) )

цв2. имсхов ( „Превод слике доле и десно“ , имаге_транслатион )

# сада ћемо користити горњу НумПи матрицу да померимо слике дуж

# правци к-осе (лево) и и-осе (горе).

# Овде ћемо померити слике за 50 пиксела улево

# и 90 пиксела према горе.

превод_мат = на пример. флоат32 ( [ [ 1 , 0 , - педесет ] , [ 0 , 1 , - 90 ] ] )

имаге_транслатион = цв2. варпАффине ( слика , превод_мат ,

( слика. облик [ 1 ] , слика. облик [ 0 ] ) )

цв2. имсхов ( „Превод слике горе и лево“ , имаге_транслатион )

цв2. ваитКеи ( 0 )

Редови 1 до 5: Увозимо све потребне пакете за овај програм, као што су ОпенЦВ, аргпарсер и НумПи. Имајте на уму да постоји још једна библиотека која је имутил. Ово није пакет ОпенЦВ-а. Ово је само библиотека која ће лако приказати исту обраду слике.



Имутили библиотеке неће бити аутоматски укључени када инсталирамо ОпенЦВ. Дакле, да бисмо инсталирали имутилс, морамо да користимо следећи метод:

пип инсталл имутилс

Редови 8 до 15: Направили смо наш агрпарсер и учитали нашу слику.

Редови 24 до 25: Овај одељак програма је место где се преводи. Матрица за превођење нам говори за колико пиксела ће слика бити померена горе или доле или лево или десно. Пошто ОпенЦВ захтева да вредност матрице буде у низу са покретним зарезом, матрица за превођење узима вредности у низовима са покретним зарезом.

Први ред матрице превода изгледа овако:

Овај ред матрице је за к-осу. Вредност т Икс ће одлучити да ли ће слика бити померена на леву или десну страну. Ако проследимо негативну вредност, то значи да ће слика бити померена на леву страну, а ако је вредност позитивна, то значи да ће слика бити померена на десну страну.

Сада ћемо дефинисати други ред матрице на следећи начин:

Овај ред матрице је за и-осу. Вредност т И ће одлучити да ли ће слика бити померена нагоре или надоле. Ако проследимо негативну вредност, то значи да ће слика бити померена нагоре, а ако је вредност позитивна, то значи да ће слика бити померена на доњу страну.

У претходном програму у реду 24 дефинишемо т Икс = 30 и т И = 70. Дакле, померамо слику за 30 пиксела ка десној страни и 70 пиксела наниже.

Али главни процес превођења слике одвија се у реду 25, где дефинишемо матрицу превођења цв2.варпАффине . У овој функцији прослеђујемо три параметра: први параметар је слика, други параметар је транслациона матрица, а трећи параметар је димензија слике.

27. ред: Линија 27 ће приказати резултат у излазу.

Сада ћемо имплементирати још једну транслациону матрицу за лево и наопако. За ово морамо да дефинишемо вредности у негативним вредностима.

Линије 33 до 34: У претходном програму у реду 33 дефинишемо т Икс = -50 и т И = -90. Дакле, померамо слику за 50 пиксела према левој страни и 90 пиксела према горе. Али главни процес превођења слике одвија се у реду 34, где дефинишемо матрицу превођења цв2.варпАффине .

Линија 36 : Линија 36 ће приказати резултат као што је приказано у излазу.

Да бисмо покренули претходни код, морамо дати путању слике као што је дато у наставку.

Излаз: питхон транслате.пи –слика веверица.јпг

Сада ћемо имплементирати исти програм за превођење слика користећи имутил библиотека. Ова библиотека је веома лака за коришћење за обраду слика. У овој библиотеци не морамо да размишљамо о цв2.варпАффине јер ће се за ово побринути ова библиотека. Хајде да применимо овај програм за превођење слика користећи библиотеку имутилс.

Питхон код: Име следећег програма задржаћемо као транслате_имутилс.пи .

# увозите потребне пакете

увоз нумпи као што на пример.

увоз аргпарсе

увоз имутил

увоз цв2

# Ова функција имплементира превод слике и

# враћа преведену слику функцији која позива.

деф превести ( слика , Икс , И ) :

матрица_превођења = на пример. флоат32 ( [ [ 1 , 0 , Икс ] , [ 0 , 1 , И ] ] )

имаге_транслатион = цв2. варпАффине ( слика , матрица_превођења ,

( слика. облик [ 1 ] , слика. облик [ 0 ] ) )

повратак имаге_транслатион

# конструише парсер аргумената и анализира аргументе

ап = аргпарсе. АргументПарсер ( )

ап. адд_аргумент ( '-и' , '--слика' , потребан = Истина , помоћ = 'Пут до слике' )

аргс = чији ( ап. парсе_аргс ( ) )

# учитајте слику и прикажите на екрану

слика = цв2. имреад ( аргс [ 'слика' ] )

цв2. имсхов ( 'Оригинал_имаге' , слика )

имаге_транслатион = имутил. превести ( слика , 10 , 70 )

цв2. имсхов ( „Превод слике на десну и доњу страну“ ,

имаге_транслатион )

цв2. ваитКеи ( 0 )

Редови 9 до 13: Овај део програма је место где се преводи. Транслациона матрица нас обавештава за колико пиксела ће слика бити померена горе или доле или лево или десно.

Ове линије су већ објашњене, али сада ћемо направити функцију која се зове транслате () и послати три различита параметра у њу. Сама слика служи као први параметар. Вредности к и и матрице транслације одговарају другом и трећем параметру.

Белешка : Нема потребе да дефинишете ову функцију превођења унутар програма јер је већ укључена у пакет библиотеке имутилс. Користио сам га у оквиру програма ради једноставног објашњења. Ову функцију можемо позвати директно са имутилима, као што је приказано у реду 24.

24. ред: Претходни програм ће показати да у реду 24 дефинишемо тк = 10 и ти = 70. Дакле, померамо слику за 10 пиксела према десној страни и 70 пиксела наниже.

У овом програму нас не занимају никакве цв2.варпАффине функције јер су оне већ унутар пакета библиотеке имутилс.

Да бисмо покренули претходни код, морамо дати путању слике, као што је дато у наставку:

Излаз:

питхон имутилс. пи --слика веверица. јпг

2. Ротација слике

Прошли смо кроз како да преведемо (тј. померимо) слику нагоре, надоле, лево и десно у претходној лекцији (или било којој комбинацији). Затим ћемо разговарати о ротацији која се односи на обраду слике.

Слика се ротира за угао, тета, у процесу познатом као ротација. Угао за који ротирамо слику биће представљен тета. Поред тога, накнадно ћу обезбедити функцију за погодност ротирања да учиним ротирање слика једноставнијим.

Слично транслацији, и можда није изненађујуће, ротација за угао, тета се одређује изградњом матрице М у следећем формату:

Ова матрица може да ротира вектор тета степени (у смеру супротном од казаљке на сату) око исходишта дате (к, и) - Декартове равни. Обично, у овом сценарију, почетак би био центар слике, али у стварности, можемо означити било коју случајну (к, и) тачку као наш центар ротације.

Ротирана слика Р се затим креира од оригиналне слике И користећи једноставно множење матрице: Р = ИМ

ОпенЦВ, с друге стране, додатно нуди капацитет за (1) скалирање (тј. промену величине) слике и (2) нуди произвољни центар ротације за обављање ротације.

Наша модификована матрица ротације М је приказана у наставку:

Почнимо отварањем и генерисањем нове датотеке под називом ротирати.пи :

# увоз потребних пакета

увоз нумпи као што на пример.

увоз аргпарсе

увоз имутил

увоз цв2

# креирање објекта аргументпарсер и рашчлањивање аргумента

апобј = аргпарсе. АргументПарсер ( )

апобј. адд_аргумент ( '-к' , '--слика' , потребан = Истина , помоћ = 'пут слике' )

аргументима = чији ( апобј. парсе_аргс ( ) )

слика = цв2. имреад ( аргументима [ 'слика' ] )

цв2. имсхов ( 'Оригинал_имаге' , слика )

# Израчунајте центар слике користећи димензије слике.

( висина , ширина ) = слика. облик [ : 2 ]

( центерКс , центерИ ) = ( ширина / 2 , висина / 2 )

# Сада, користећи цв2, ротирати ћемо слику за 55 степени до

# одредите матрицу ротације користећи гетРотатионМатрик2Д()

ротатионМатрик = цв2. гетРотатионМатрик2Д ( ( центерКс , центерИ ) , 55 , 1.0 )

ротатедИмаге = цв2. варпАффине ( слика , ротатионМатрик , ( ширина , висина ) )

цв2. имсхов ( „Ротирана слика за 55 степени“ , ротатедИмаге )

цв2. ваитКеи ( 0 )

# Слика ће сада бити ротирана за -85 степени.

ротатионМатрик = цв2. гетРотатионМатрик2Д ( ( центерКс , центерИ ) , - 85 , 1.0 )

ротатедИмаге = цв2. варпАффине ( слика , ротатионМатрик , ( ширина , висина ) )

цв2. имсхов ( „Ротирана слика за -85 степени“ , ротатедИмаге )

цв2. ваитКеи ( 0 )

Редови 1 до 5: Увозимо све потребне пакете за овај програм, као што су ОпенЦВ, аргпарсер и НумПи. Имајте на уму да постоји још једна библиотека која је имутил. Ово није пакет ОпенЦВ-а. Ово је само библиотека која ће се користити за лако приказивање исте обраде слике.

Имутили библиотеке неће бити аутоматски укључени када инсталирамо ОпенЦВ. ОпенЦВ инсталира имутилс. Морамо да користимо следећи метод:

пип инсталл имутилс

Редови 8 до 14: Направили смо наш агрпарсер и учитали нашу слику. У овом аргпарсеру користимо само један аргумент слике, који ће нам рећи путању слике коју ћемо користити у овом програму да демонстрирамо ротацију.

Када ротирамо слику, морамо дефинисати тачку стожера ротације. Већину времена ћете желети да ротирате слику око њеног центра, али ОпенЦВ вам омогућава да уместо тога изаберете било коју случајну тачку. Хајде да једноставно ротирамо слику око њеног центра.

Линије 17 до 18 узмите ширину и висину слике, а затим поделите сваку димензију са два да бисте утврдили центар слике.

Конструишемо матрицу за ротирање слике на исти начин на који смо дефинисали матрицу за превођење слике. Само ћемо позвати цв2.гетРотатионМатрик2Д функционишу на линији 22 уместо да ручно креирају матрицу користећи НумПи (што може бити мало гломазно).

Тхе цв2.гетРотатионМатрик2Д функција захтева три параметра. Први улаз је жељени угао ротације (у овом случају центар слике). Тхета се затим користи да одредимо за колико (у супротном смеру казаљке на сату) степени ћемо ротирати слику. Овде ћемо ротирати слику за 45 степени. Коначна опција је повезана са величином слике.

Без обзира на то што још нисмо разговарали о скалирању слике, овде можете навести број у покретном зарезу са 1.0 који означава да слику треба користити у оригиналним пропорцијама. Међутим, ако унесете вредност 2,0, слика би се удвостручила. Број од 0,5 на тај начин смањује величину слике.

Линије 22 до 23: Након што смо примили нашу матрицу ротације М од цв2.гетРотатионМатрик2Д функцију, ротирамо нашу слику користећи цв2.варпАффине техника на линији 23. Први улаз функције је слика коју желимо да ротирамо. Затим се дефинише ширина и висина наше излазне слике, заједно са нашом матрицом ротације М. На линији 23, слика се затим ротира за 55 степени.

Можете приметити да је наша слика ротирана.

Редови 28 до 30 чине другу ротацију. Редови 22–23 кода су идентични, осим што се овај пут ротирамо за -85 степени у односу на 55.

Једноставно смо ротирали слику око њеног центра до ове тачке. Шта ако желимо да ротирамо слику око насумичне тачке?

Почнимо отварањем и генерисањем нове датотеке под називом ротате.пи:

# увоз потребних пакета

увоз нумпи као што на пример.

увоз аргпарсе

увоз имутил

увоз цв2

# креирање објекта аргументпарсер и рашчлањивање аргумента

ап_обј = аргпарсе. АргументПарсер ( )

ап_обј. адд_аргумент ( '-к' , '--слика' , потребан = Истина , помоћ = 'пут слике' )

расправа = чији ( ап_обј. парсе_аргс ( ) )

# учитајте слику и прикажите на екрану

слика = цв2. имреад ( расправа [ 'слика' ] )

цв2. имсхов ( 'Оригинал_имаге' , слика )

# Израчунајте центар слике користећи димензије слике.

( висина , ширина ) = слика. облик [ : 2 ]

( центерКс , центерИ ) = ( ширина / 2 , висина / 2 )

# Сада, користећи цв2, ротирати ћемо слику за 55 степени до

# одредите матрицу ротације користећи гетРотатионМатрик2Д()

ротатионМатрик = цв2. гетРотатионМатрик2Д ( ( центерКс , центерИ ) , 55 , 1.0 )

ротатедИмаге = цв2. варпАффине ( слика , ротатионМатрик , ( ширина , висина ) )

цв2. имсхов ( „Ротирана слика за 55 степени“ , ротатедИмаге )

цв2. ваитКеи ( 0 )

# Слика ће сада бити ротирана за -85 степени.

ротатионМатрик = цв2. гетРотатионМатрик2Д ( ( центерКс , центерИ ) , - 85 , 1.0 )

ротатедИмаге = цв2. варпАффине ( слика , ротатионМатрик , ( ширина , висина ) )

цв2. имсхов ( „Ротирана слика за -85 степени“ , ротатедИмаге )

цв2. ваитКеи ( 0 )

# ротација слике из неке произвољне тачке, а не из центра

ротатионМатрик = цв2. гетРотатионМатрик2Д ( ( центерКс - 40 , центарИ - 40 ) , 55 , 1.0 )

ротатедИмаге = цв2. варпАффине ( слика , ротатионМатрик , ( ширина , висина ) )

цв2. имсхов ( „Ротација слике из произвољних тачака“ , ротатедИмаге )

цв2. ваитКеи ( 0 )

Линије 34 до 35: Овај код би требало да изгледа прилично уобичајено за ротирање објекта. Да бисте ротирали слику око тачке 40 пиксела улево и 40 пиксела изнад њеног центра, налажемо цв2.гетРотатионМатрик2Д функција да обрати пажњу на свој први параметар.

Слика настала када применимо ову ротацију је приказана у наставку:

Јасно можемо видети да је центар ротације сада (к, и)-координата, која је 40 пиксела лево и 40 пиксела изнад израчунатог центра слике.

3. Аритметика слике

У ствари, аритметика слике је само додавање матрице са неколико додатних ограничења на типове података које ћемо покрити касније.

Хајде да одвојимо тренутак да пређемо на неке лепе основе линеарне алгебре.

Размислите о комбиновању следеће две матрице:

Какав би резултат дало сабирање матрице? Једноставан одговор је збир уноса матрице, елемент по елемент:

Довољно једноставно, зар не?

Сви разумемо основне операције сабирања и одузимања у овом тренутку. Међутим, морамо имати на уму ограничења која намећу наш простор боја и тип података док радимо са сликама.

Пиксели у РГБ сликама, на пример, падају између [0, 255]. Шта се дешава ако покушамо да додамо 10 пикселу са интензитетом од 250 док га гледамо?

Дошли бисмо до вредности од 260 ако бисмо применили стандардне аритметичке принципе. 260 није важећа вредност, пошто су РГБ слике представљене као 8-битни цели бројеви без предзнака.

Па шта би требало да се деси? Да ли треба да извршимо проверу да бисмо се уверили да ниједан пиксел није изван опсега [0, 255], исечући сваки пиксел да има вредност између 0 и 255?

Или се „замотамо“ и извршимо операцију модула? У складу са правилима модула, додавањем 10 на 255 само би се добила вредност од 9.

Како треба поступати са сабирањем и одузимањем сликама изван опсега [0, 255]?

Истина је да не постоји исправна или погрешна техника; све зависи од тога како радите са својим пикселима и шта се надате да ћете постићи.

Али запамтите да постоје разлике између сабирања у ОпенЦВ-у и сабирања у НумПи-у. Аритметику модула и „омотавање“ обавиће НумПи. Насупрот томе, ОпенЦВ ће извршити клипинг и побринути се да вредности пиксела никада не напусте опсег [0, 255].

Почнимо креирањем нове датотеке под називом аритметика.пи и отворите га:

# питхон аритхметиц.пи --имаге веверица.јпг

# увоз потребних пакета

увоз нумпи као што на пример.

увоз аргпарсе

увоз имутил

увоз цв2

# креирање објекта аргументпарсер и рашчлањивање аргумента

апОбј = аргпарсе. АргументПарсер ( )

апОбј. адд_аргумент ( '-к' , '--слика' , потребан = Истина , помоћ = 'пут слике' )

аргументима = чији ( апОбј. парсе_аргс ( ) )

слика = цв2. имреад ( аргументима [ 'слика' ] )

цв2. имсхов ( 'Оригинал_имаге' , слика )

'''

Вредности наших пиксела ће бити у опсегу [0, 255]

пошто су слике НумПи низови, који се чувају као неозначени 8-битни цели бројеви.

Када користите функције као што су цв2.адд и цв2.субтрацт, вредности ће бити исечене

овом опсегу чак и ако се додају или одузму изван

[0, 255] опсег. Ево илустрације:

'''


принт ( 'максимално 255: {}' . формату ( стр ( цв2. додати ( на пример. уинт8 ( [ 201 ] ) ,

на пример. уинт8 ( [ 100 ] ) ) ) ) )

принт ( 'минимум 0: {}' . формату ( стр ( цв2. одузимати ( на пример. уинт8 ( [ 60 ] ) ,

на пример. уинт8 ( [ 100 ] ) ) ) ) )

'''

Када радите аритметичке операције са овим низовима користећи НумПи,

вредност ће се омотати уместо да буде исечена на

[0, 255] опсег. Када користите слике, важно је да ово сачувате

на уму.

'''


принт ( 'замотати око: {}' . формату ( стр ( на пример. уинт8 ( [ 201 ] ) + нпр. уинт8 ( [ 100 ] ) ) ) )

принт ( 'замотати око: {}' . формату ( стр ( на пример. уинт8 ( [ 60 ] ) - на пример. уинт8 ( [ 100 ] ) ) ) )

'''

Хајде да помножимо осветљеност сваког пиксела на нашој слици са 101.

Да бисмо то урадили, генеришемо НумПи низ исте величине као и наша матрица,

испуњен јединицама и помножите га са 101 да бисте добили попуњен низ

са 101с. На крају спајамо две слике.

Приметићете да је слика сада „светлија“.

'''


Матрик = на пример. оне ( слика. облик , дтипе = 'уинт8' ) * 101

имаге_аддед = цв2. додати ( слика , Матрик )

цв2. имсхов ( „Резултат додане слике“ , имаге_аддед )

#На сличан начин можемо учинити нашу слику тамнијом узимањем

# 60 удаљен од свих пиксела.

Матрик = на пример. оне ( слика. облик , дтипе = 'уинт8' ) * 60

имаге_субтрацтед = цв2. одузимати ( слика , Матрик )

цв2. имсхов ( „Резултат одузете слике“ , имаге_субтрацтед )

цв2. ваитКеи ( 0 )

Линије од 1 до 16 ће се користити за обављање нашег нормалног процеса, који подразумева увоз наших пакета, конфигурисање нашег парсера аргумената и учитавање наше слике.

Сећате се како сам раније расправљао о разлици између додавања ОпенЦВ и НумПи? Сада када смо то темељно покрили, погледајмо конкретан случај да бисмо били сигурни да смо га схватили.

Дефинисана су два 8-битна низа целих бројева НумПи без предзнака ред 26 . Вредност 201 је једини елемент у првом низу. Иако је само један члан у другом низу, он има вредност 100. Вредности се затим додају помоћу ОпенЦВ-ове цв2.адд функције.

Шта очекујете да ће бити резултат?

У складу са конвенционалним аритметичким принципима, одговор би требало да буде 301. Али запамтите да имамо посла са 8-битним целим бројевима без предзнака, који могу бити само у опсегу [0, 255]. Пошто користимо методу цв2.адд, ОпенЦВ управља сечењем и осигурава да додавање само враћа максимални резултат од 255.

Први ред листе испод показује исход покретања овог кода:

аритметика. пи

максимум од 255 : [ [ 255 ] ]

Збир је заиста произвео број од 255.

Након тога, ред 26 користи цв2.субтрацт за постизање одузимања. Још једном дефинишемо два НумПи низа 8-битних целих бројева без предзнака са једним елементом у сваком. Вредност првог низа је 60, док је вредност другог низа 100.

Наша аритметика налаже да одузимање треба да резултира вредношћу од -40, али ОпенЦВ још једном обрађује исечак уместо нас. Откривамо да је вредност смањена на 0. Наш резултат у наставку показује ово:

аритметика. пи

минимум од 0 : [ [ 0 ] ]

Користећи цв2, одузмите 100 од 60 одузмите, дајући вредност 0.

Али шта се дешава ако користимо НумПи уместо ОпенЦВ-а да извршимо прорачуне?

Редови 38 и 39 позабавите овим питањем.

Прво, дефинисана су два 8-битна неозначена целобројна НумПи низа са по једним елементом. Вредност првог низа је 201, док је вредност другог низа 100. Наш сабирак би био скраћен, а вредност од 255 би била враћена ако бисмо користили функцију цв2.адд.

НумПи, с друге стране, „омотава“ и ради модуло аритметику уместо сечења. НумПи се окреће на нулу када се достигне вредност од 255, а затим наставља са бројањем све док се не достигне 100 корака. Ово потврђује први ред излаза, који је приказан испод:

аритметика. пи
замотати око: [ Четири, пет ]

Затим се дефинишу још два НумПи низа, један са вредношћу 50, а други са 100. Ово одузимање би се смањило помоћу методе цв2.субтрацт да би се вратио резултат од 0. Али свесни смо да уместо сечења, НумПи извршава модуло аритметика. Уместо тога, модуло процедуре се заокружују и почињу да броје уназад од 255 када се 0 постигне током одузимања. Ово можемо видети из следећег излаза:

аритметика. пи

замотати око: [ 207 ]

Још једном, наш терминални излаз показује разлику између сечења и премотавања:

Кључно је да имате на уму жељени резултат када изводите целобројну аритметику. Да ли желите да било које вредности изван опсега [0, 255] буду исечене? Након тога користите уграђене аритметичке технике ОпенЦВ-а.

Да ли желите да се вредности премотају ако су изван опсега [0, 255] и аритметичких операција модула? НумПи низови се затим једноставно додају и одузимају као и обично.

Линија 48 дефинише једнодимензионални НумПи низ са истим димензијама као наша слика. Још једном, осигуравамо да је наш тип података 8-битни цели бројеви без предзнака. Ми само помножимо нашу матрицу једноцифрених вредности са 101 да бисмо је попунили вредностима од 101 уместо 1. Коначно, користимо функцију цв2.адд да бисмо оригиналној слици додали нашу матрицу од 100. Ово повећава интензитет сваког пиксела за 101, истовремено осигуравајући да све вредности које покушају да пређу 255 буду исечене у опсег [0, 255].

Посматрајте како је слика приметно светлија и изгледа „испранија“ од оригинала. То је зато што ми усмеравамо пикселе ка светлијим бојама повећавајући њихов интензитет пиксела за 101.

Да бисмо одузели 60 од сваког интензитета пиксела слике, прво успостављамо други НумПи низ на линији 54 који је испуњен 60-има.

Исходи овог одузимања су приказани на следећој слици:

Предмети око нас изгледају знатно тамнији него раније. То је зато што одузимањем 60 од сваког пиксела померамо пикселе у РГБ простору боја у тамније области.

4. Окретање слике

Слично ротацији, окретање слике преко њене к или и-осе је још једна опција коју нуди ОпенЦВ. Чак и ако се операције окретања не користе тако често, познавање њих је невероватно корисно из различитих разлога које можда нећете одмах уочити.

Развијамо класификатор машинског учења за малу стартап компанију која настоји да идентификује лица на сликама. Да би наш систем „научио“ шта је лице, потребна нам је нека врста скупа података са узорцима лица. Нажалост, компанија нам је дала само мали скуп података од 40 лица и нисмо у могућности да прикупимо више информација.

Шта онда да радимо?

Пошто лице остаје лице без обзира да ли је пресликано или не, у могућности смо да хоризонтално окренемо сваку слику лица и користимо пресликане верзије као додатне податке за обуку.

Овај пример може изгледати глупо и вештачко, али није. Пребацивање је намерна стратегија коју користе јаки алгоритми дубоког учења за производњу више података током фазе обуке.

Из претходног је јасно да методе обраде слике које научите у овом модулу служе као основа за веће системе компјутерског вида.

Циљеви:

Помоћу цв2.флип функција, научићете како да окренете слику и хоризонтално и вертикално у овој сесији.

Окретање је следећа манипулација сликама коју ћемо проучавати. Осе к и и слике могу се окренути или чак обе. Пре него што заронимо у кодирање, најбоље је прво погледати резултате окретања слике. Погледајте слику која је хоризонтално окренута на следећој слици:


Обратите пажњу на то како је наша оригинална слика на левој страни и како је слика хоризонтално пресликана на десној страни.

Почнимо креирањем нове датотеке под називом флиппинг.пи .

Видели сте пример преокретања слике, па хајде да испитамо код:

# питхон флиппинг.пи --имаге куиррел.јпг

# увоз потребних пакета

увоз аргпарсе

увоз цв2

# креирање објекта парсера аргумената и рашчлањивање аргумента

апОбј = аргпарсе. АргументПарсер ( )

апОбј. адд_аргумент ( '-и' , '--слика' , потребан = Истина , помоћ = 'пут слике' )

расправа = чији ( апОбј. парсе_аргс ( ) )

слика = цв2. имреад ( расправа [ 'слика' ] )

цв2. имсхов ( 'Оригинал' , слика )

# хоризонтално окрените слику

имагефлиппед = цв2. флип ( слика , 1 )

цв2. имсхов ( „Хоризонтално окренута слика“ , имагефлиппед )

# вертикално окрените слику

имагефлиппед = цв2. флип ( слика , 0 )

цв2. имсхов ( „Окренута слика вертикално“ , имагефлиппед )

# слика преокренути дуж обе осе

имагефлиппед = цв2. флип ( слика , - 1 )

цв2. имсхов ( „Обрнуто хоризонтално и вертикално“ , имагефлиппед )

цв2. ваитКеи ( 0 )

Кораци које предузимамо за увоз наших пакета, рашчлањивање наших улаза и учитавање наше слике са диска се обрађују у л инес од 1 до 12 .

Позивањем функције цв2.флип он Линија 15 , једноставно је окренути слику хоризонтално. Слика коју желимо да окренемо и одређени код или ознака која одређује како да окренемо слику су два аргумента потребна за методу цв2.флип.

Вредност преокренутог кода од 1 значи да ћемо ротирати слику око и-осе да бисмо је окренули хоризонтално ( Линија 15 ). Ако наведемо флип код од 0, желимо да ротирамо слику око к-осе ( Линија 19 ). Негативан флип код ( Линија 23 ) ротира слику на обе осе.

Један од најлакших примера у овој теми је окретање слике, што је основно.

Затим ћемо разговарати о изрезивању слика и употребити НумПи резове низа за издвајање одређених делова слике.

5. Изрезивање слике

Обрезивање, као што назив имплицира, је процес одабира и уклањања региона од интереса (или једноставно РОИ), што је област слике која нас занима.

Лице би требало да буде исечено са слике за апликацију за детекцију лица. Поред тога, ако смо креирали Питхон скрипту за проналажење паса на сликама, можда бисмо желели да исечемо пса са слике када га лоцирамо.

Циљеви: Наш главни циљ је да се упознамо и са лакоћом користимо НумПи резање низа за исецање подручја са слике.

Обрезивање : Када исечемо слику, наш циљ је да елиминишемо спољашње елементе који нас не занимају. Процес избора нашег РОИ се често назива избором региона од интереса.

Креирајте нову датотеку под називом цроп.пи , отворите га и додајте следећи код:

# питхон цроп.пи

# увоз потребних пакета

увоз цв2

# учитавање слике и приказ на екрану

слика = цв2. имреад ( 'скуиррел.јпг' )

принт ( слика. облик )

цв2. имсхов ( 'Оригинал' , слика )

# НумПи низови се користе за брзо исецање слике

# исећи ћемо лице веверице са слике

веверица = слика [ 35 : 90 , 35 : 100 ]

цв2. имсхов ( 'лице веверице' , веверица )

цв2. ваитКеи ( 0 )

# А сада, овде ћемо исецати цело тело

# од веверице

скуиррелбоди = слика [ 35 : 148 , 23 : 143 ]

цв2. имсхов ( 'Тело веверице' , скуиррелбоди )

цв2. ваитКеи ( 0 )

Приказаћемо исецање у Питхон-у и ОпенЦВ-у користећи слику коју учитавамо са диска Линије 5 и 6 .

Оригинална слика коју ћемо изрезати

Користећи само основне технике обрезивања, циљ нам је да одвојимо лице веверице и тело веверице од околног подручја.

Користићемо наше претходно знање о слици и ручно доставити НумПи низ резова где постоје тело и лице. У нормалним условима, генерално бисмо користили машинско учење и алгоритме компјутерског вида да бисмо препознали лице и тело на слици. Али хајде да ствари за сада буду јасни и избегавајмо коришћење било каквих модела детекције.

Можемо идентификовати лице на слици само једном линијом кода. Линија 13 , За издвајање правоугаоног дела слике, почевши од (35, 35), пружамо НумПи резове низа (90, 100). Може изгледати збуњујуће што обрезивање хранимо индексима у редоследу висина-прва и ширина-друга као што радимо, али имајте на уму да ОпенЦВ складишти слике као НумПи низове. Као резултат тога, морамо дати вредности за и-осу пре к-осе.

НумПи захтева следећа четири индекса да би извршио наше исецање:

Почетак и: И-координата на почетку. За овај пример, почињемо од и=35.

Крај и: Координата и на крају. Наш усев ће се зауставити када је и = 90.

Почни к: Координата почетка к пресека. Жетва почиње на к=35.

Крај к: Координата к-осе краја пресека. На к=100, наш пресек је готов.

Слично томе, исечемо регионе (23, 35) и (143, 148) са оригиналне слике да бисмо извукли цело тело са слике на Линија 19 .

Можете приметити да је слика исечена да прикаже само тело и лице.

6. Промена величине слике

Процес повећања или смањења ширине и висине слике познат је као скалирање или једноставно промена величине. Омјер ширине и висине слике, који је пропорција ширине слике и њене висине, треба узети у обзир приликом промјене величине слике. Занемаривање односа ширине и висине може довести до слика које су скалиране и изгледају компримовано и изобличено:

Наша почетна слика је на левој страни. На десној страни ћете видети две слике које су скалиране без одржавања односа ширине и висине, изобличујући пропорцију ширине слике и њене висине. Када мењате величину слика, генерално треба да узмете у обзир однос страница.

Техника интерполације коју користи наш алгоритам за промену величине такође мора узети у обзир циљ функције интерполације да користи ове комшилуке пиксела за повећање или смањење величине слике.

Генерално, смањење величине слике је далеко ефикасније. То је зато што је уклањање пиксела са слике све што функција интерполације треба да уради. С друге стране, метода интерполације би морала да „попуни празнине“ између пиксела који раније нису постојали ако би се величина слике повећала.

Имамо нашу оригиналну слику на левој страни. Слика је смањена на половину своје првобитне величине у центру, али осим тога, није дошло до губитка „квалитета“ слике. Ипак, величина слике је знатно повећана на десној страни. Сада изгледа „надувано“ и „пикселизирано“.

Као што сам раније рекао, обично ћете желети да смањите величину слике уместо да је повећате. Смањењем величине слике, анализирамо мање пиксела и морамо да се бавимо мање „шума“, што алгоритме за обраду слике чини бржим и прецизнијим.

Превођење и ротација су две трансформације слике које смо до сада обрадили. Сада ћемо испитати како да променимо величину слике.

Није изненађујуће да ћемо променити величину наших слика помоћу методе цв2.ресизе. Као што сам раније навео, морамо узети у обзир однос ширине и висине слике када користимо овај метод. Али пре него што уђемо сувише дубоко у специфичности, дозволите ми да вам дам илустрацију:

# питхон ресизе.пи --имаге веверица.јпг

# увоз потребних пакета

увоз аргпарсе

увоз цв2

# креирање објекта парсера аргумената и рашчлањивање аргумента

апОбј = аргпарсе. АргументПарсер ( )

апОбј. адд_аргумент ( '-к' , '--слика' , потребан = Истина , помоћ = 'пут слике' )

аргументима = чији ( апОбј. парсе_аргс ( ) )

# учитајте слику и прикажите на екрану

слика = цв2. имреад ( аргументима [ 'слика' ] )

цв2. имсхов ( 'Оригинал' , слика )

# Да бисте спречили да слика изгледа искривљена, однос ширине и висине

# мора се узети у обзир или деформисати; дакле, схватамо шта

# однос нове слике према тренутној слици.

# Хајде да направимо ширину наше нове слике 160 пиксела.

аспект = 160.0 / слика. облик [ 1 ]

димензија = ( 160 , инт ( слика. облик [ 0 ] * аспект ) )

# овај ред ће показати стварне операције промене величине

ресизедимаге = цв2. промените величину ( слика , димензија , интерполација = цв2. ИНТЕР_АРЕА )

цв2. имсхов ( „Промењена величина ширине слике“ , ресизедимаге )

# Шта ако желимо да променимо висину слике? - помоћу

# исти принцип, можемо израчунати пропорцију на основу

# на висини, а не на ширини. Хајде да направимо скалу

Висина # слике 70 пиксела.

аспект = 70.0 / слика. облик [ 0 ]

димензија = ( инт ( слика. облик [ 1 ] * аспект ) , 70 )

# извршите промену величине

ресизедимаге = цв2. промените величину ( слика , димензија , интерполација = цв2. ИНТЕР_АРЕА )

цв2. имсхов ( „Промењена величина висине слике“ , ресизедимаге )

цв2. ваитКеи ( 0 )

Линије 1-14 , Након увоза наших пакета и конфигурисања нашег парсера аргумената, учитаћемо и приказати нашу слику.

Редови 20 и 21: Одговарајуће кодирање почиње у овим редовима . Омјер слике мора се узети у обзир приликом промјене величине. Пропорција између ширине и висине слике позната је као однос ширине и висине слике.

Висина Ширина је однос ширине и висине.

Ако не узмемо у обзир однос ширине и висине, резултати наше промене величине ће постати изобличени.

на Линија 20 , прорачун промењене величине је урађен. Дајемо ширину наше нове слике као 160 пиксела у овој линији кода. Једноставно дефинишемо наш однос (аспецтратио) као нову ширину (160 пиксела) подељену са старом ширином, којој приступамо помоћу слике, да бисмо израчунали однос нове висине и старе висине. облик[1].

Нове димензије слике на Линија 21 може се израчунати сада када знамо наш однос. Још једном, нова слика ће имати ширину од 160 пиксела. Након множења старе висине нашим односом и претварања резултата у цео број, висина се израчунава. Извођењем ове операције можемо задржати оригинални однос ширине и висине слике.

Линија 24 је место где се слика заиста мења. Слика којој желимо да променимо величину је први аргумент, а други су димензије које смо израчунали за нову слику. Наш метод интерполације, који је алгоритам за промену величине стварне слике, је последњи параметар.

Коначно, на Линија 25 , приказујемо нашу увећану слику.

Редефинишемо наш однос (аспецтратио) на Линија 31 . Висина наше нове слике биће 70 пиксела. Делимо 70 са оригиналном висином да бисмо добили нови однос висине и првобитне висине.

Затим утврђујемо димензије нове слике. Нова слика ће имати висину од 70 пиксела, што је већ познато. Још једном можемо задржати оригинални однос ширине и висине слике тако што ћемо стару ширину помножити односом да бисмо произвели нову ширину.

Слика се тада заправо мења Линија 35 , и приказује се на Линија 36.

Овде можемо видети да смо смањили ширину и висину наше оригиналне слике уз задржавање односа ширине и висине. Наша слика би изгледала искривљена ако се не одржава однос ширине и висине слике.

Закључак

У овом блогу смо проучавали основне различите концепте обраде слика. Видели смо превод слика уз помоћ ОпенЦВ пакета. Видели смо методе за померање слике горе, доле, десно и лево. Ове методе су веома корисне када креирамо скуп података сличних слика које ћемо дати као скуп података за обуку, тако да ће машина видети различите слике чак и ако су исте. Овај чланак вас је такође научио како да ротирате слику око било које тачке у Декартовом простору користећи матрицу ротације. Затим сте открили како ОпенЦВ ротира слике користећи ову матрицу и видели неколико илустрација слика које се окрећу.

Две фундаменталне (али значајне) слике аритметичке операције сабирања и одузимања су испитане у овом одељку. Као што видите, сабирање и одузимање основних матрица су све аритметичке операције слике.

Поред тога, користили смо ОпенЦВ и НумПи да бисмо истражили посебности аритметике слика. Ова ограничења морате имати на уму, иначе ризикујете да добијете неочекиване исходе када извршавате аритметичке операције на вашим сликама.

Важно је запамтити да иако НумПи изводи модулну операцију и „замотава“, ОпенЦВ сабирање и одузимање секу вредности изван опсега [0, 255] да би се уклопиле у опсег. Када развијате сопствене апликације за компјутерски вид, запамтите ово ће вам помоћи да избегнете лов на незгодне грешке.

Окретање слика је несумњиво једна од једноставнијих идеја које ћемо истражити у овом курсу. Окретање се често користи у машинском учењу за генерисање више узорака података за обуку, што резултира снажнијим и поузданијим класификаторима слика.

Такође смо научили како да користимо ОпенЦВ за промену величине слике. Од кључне је важности да узмете у обзир и метод интерполације који користите и однос ширине и висине ваше оригиналне слике када мењате величину тако да резултат не изгледа изобличен.

На крају, кључно је запамтити да ако је квалитет слике проблем, увек је најбоље прећи са веће на мању слику. У већини случајева, повећање слике ствара артефакте и деградира њен квалитет.