{"id":112,"date":"2022-07-27T08:57:51","date_gmt":"2022-07-27T08:57:51","guid":{"rendered":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/?post_type=chapter&#038;p=112"},"modified":"2022-12-16T07:44:35","modified_gmt":"2022-12-16T07:44:35","slug":"metody-przetwarzania-obrazu","status":"web-only","type":"chapter","link":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/chapter\/metody-przetwarzania-obrazu\/","title":{"raw":"Metody przetwarzania obrazu","rendered":"Metody przetwarzania obrazu"},"content":{"raw":"<p style=\"text-align: justify\">Zarejestrowany obraz mo\u017cemy podda\u0107 ca\u0142emu szeregowi przekszta\u0142ce\u0144. Jednym z rodzaj\u00f3w takich przekszta\u0142ce\u0144 s\u0105 <strong>transformacje afiniczne<\/strong>. Transformacje afiniczne mog\u0105 by\u0107 stosowane, gdy mamy obraz z <strong>obszarem zainteresowania (ROI)<\/strong>, kt\u00f3ry chcemy przekszta\u0142ci\u0107, albo gdy mamy list\u0119 punkt\u00f3w, dla kt\u00f3rych obliczy\u0107 wynik przekszta\u0142cenia. W praktyce, aby zastosowa\u0107 przekszta\u0142cenie musimy obliczy\u0107 macierz przekszta\u0142ce\u0144 M, kt\u00f3ra reprezentuje <strong>transformacj\u0119<\/strong>.<\/p>\r\n<p style=\"text-align: justify\">Pierwszym przyk\u0142adem jest mo\u017cliwo\u015b\u0107 przekszta\u0142cenia obrazu, na podstawie trzech punkt\u00f3w, kt\u00f3re chcemy transformowa\u0107. Do obliczenia macierzy M, na podstawie punkt\u00f3w s\u0142u\u017cy funkcja getAffineTransform(). Przyk\u0142ad programu stosuj\u0105cy transformacj\u0119 zaprezentowano na listingu 1. Na wej\u015bciu funkcji musimy zdefiniowa\u0107 wsp\u00f3\u0142rz\u0119dne trzech punkt\u00f3w przed i po transformacji. Do zastosowania transformacji s\u0142u\u017cy funkcja warpAffin(). Na wej\u015bciu funkcji podajemy obraz, kt\u00f3ry chcemy podda\u0107 transformacji, macierz M, oraz rozmiar wyj\u015bciowy obrazu.\u00a0 Dla obliczonej raz macierzy M mo\u017cemy przekszta\u0142ci\u0107 wiele obraz\u00f3w. Wz\u00f3r transformacji mo\u017cna opisa\u0107:\u00a0 dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23). Na rysunku 1 zaprezentowano wynik transformacji oraz obraz wej\u015bciowy. Dla u\u0142atwienia interpretacji dzia\u0142ania, zastosowano funkcj\u0119 matplotlib opisuj\u0105c\u0105 wiersze i kolumny obrazu. W celu prze\u0142\u0105czania miejsca wy\u015bwietlania z wykorzystaniem biblioteki matplotlib mo\u017cna wykorzysta\u0107 opcje: <code class=\"hljs language-perl\">%matplotlib qt oraz\u00a0<\/code><code class=\"hljs language-cpp\">%matplotlib <span class=\"hljs-keyword\">inline.<\/span><\/code><\/p>\r\n<p style=\"text-align: justify\">Listing 1. Zastosowanie transformacji afinicznej.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,ch = img.shape\r\n\r\npts1 = np.float32([[50,50],[200,50],[50,200]])\r\npts2 = np.float32([[10,100],[200,50],[100,250]])\r\n\r\nM = cv2.getAffineTransform(pts1,pts2)\r\ndst = cv2.warpAffine(img,M,(cols,rows))\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n[\/code]\r\n\r\n[caption id=\"attachment_157\" align=\"aligncenter\" width=\"1024\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-1024x524.png\" alt=\"\" class=\"wp-image-157 size-large\" width=\"1024\" height=\"524\" \/> Rysunek 1. Wynik dzia\u0142ania transformacji afinicznej.[\/caption]\r\n<p style=\"text-align: justify\">Kolejnym przekszta\u0142ceniem afinicznym jest obr\u00f3t. W tym przypadku do obliczenia macierzy M wykorzystujemy funkcj\u0119 getRotationMatrix2D(). Na listingu 2 zaprezentowano przyk\u0142ad dzia\u0142ania <strong>transformacji obrotu<\/strong>. Funkcja wymaga podania\u00a0 punktu wok\u00f3\u0142 kt\u00f3rego nast\u0105pi obr\u00f3t, k\u0105t obrotu oraz skal\u0119 obrazu wyj\u015bciowego. Dla zastosowanego przypadku macierz M= \u00a01.73648178e-01, 9.84807753e-01, -5.07058978e+01; -9.84807753e-01, 1.73648178e-01, 5.79571064e+02. Na rysunku 2 przedstawiono przyk\u0142ad rotacji obrazu.<\/p>\r\n<p style=\"text-align: justify\">Listing 2. Zastosowanie transformacji obrotu.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,b = img.shape\r\n\r\nM = cv2.getRotationMatrix2D((cols\/2,rows\/2),80,1)\r\ndst = cv2.warpAffine(img,M,(cols,rows))\r\n\r\ncv2.imshow('dst',dst)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('szachownica_obrot.png',dst);\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n\r\n[\/code]\r\n\r\n[caption id=\"attachment_160\" align=\"alignnone\" width=\"1920\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a.png\" alt=\"\" class=\"wp-image-160 size-full\" width=\"1920\" height=\"983\" \/> Rysunek 2. Przyk\u0142ad transformacji obrotu.[\/caption]\r\n<p style=\"text-align: justify\">Innym rodzajem przekszta\u0142ce\u0144, s\u0105 <strong>transformacje perspektywy<\/strong>. W tym przypadku, do obliczenia macierzy M stosujemy funkcj\u0119 getPerspectiveTransform a do przekszta\u0142cenia funkcj\u0119 wrapPerspective. Nowe warto\u015bci obliczane s\u0105 z wykorzystaniem wzoru dst(x,y)=src((M11x+M12y+M13)\/(M31x+M32y+M33), (M21x+M22y+M23)\/(M31x+M32y+M33)). Przyk\u0142ad transformacji zaprezentowano na listingu 3. W przypadku zmiany perspektywy wymagane jest podanie czterech punkt\u00f3w. Wynik przyk\u0142adowej transformacji zmiany perspektywy zaprezentowano na rysunku 3.<\/p>\r\n<p style=\"text-align: justify\">Listing 3. Przyk\u0142ad transformacji perspektywy.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,ch = img.shape\r\n\r\npts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])\r\npts2 = np.float32([[0,0],[500,0],[0,500],[300,300]])\r\n\r\nM = cv2.getPerspectiveTransform(pts1,pts2)\r\n\r\ndst = cv2.warpPerspective(img,M,(300,300))\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n\r\n[\/code]\r\n\r\n[caption id=\"attachment_162\" align=\"aligncenter\" width=\"1920\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a.png\" alt=\"\" class=\"wp-image-162 size-full\" width=\"1920\" height=\"983\" \/> Rysunek 3. Przyk\u0142ad zmiany perspektywy.[\/caption]\r\n<p style=\"text-align: justify\">Istniej\u0105 inne, bardziej zaawansowane transformacje. W tym celu mo\u017cemy wykorzysta\u0107 funkcje bibliotekiOpenCV. Dla przyk\u0142adu, funkcja cartToPolar() s\u0142u\u017cy do konwersji wsp\u00f3\u0142rz\u0119dnych kartezja\u0144skich na biegunowe, funkcja polarToCart() s\u0142u\u017cy do konwersji wsp\u00f3\u0142rz\u0119dnych biegunowych na kartezja\u0144skie. Funkcja logPolar() jest wykorzystywana do przekszta\u0142ce\u0144 logarytmiczno-biegunowych. Warto zwr\u00f3ci\u0107 uwag\u0119 na inn\u0105 funkcj\u0119 remap(), kt\u00f3ra umo\u017cliwia og\u00f3lne odwzorowanie obrazu.<\/p>\r\n<p style=\"text-align: justify\">W trakcie rejestracji obrazu, mo\u017ce si\u0119 zdarzy\u0107, \u017ce fragment obrazu jest niepoprawnie zarejestrowany. Je\u015bli taka sytuacja ma miejsce, a s\u0105 to niewielkie ubytki, mo\u017cemy zastosowa\u0107 <strong>technik\u0119 renowacji<\/strong> obraz\u00f3w znan\u0105 jako <strong>inpainting<\/strong>. Przyk\u0142ad takiego ubytku mo\u017cemy zaobserwowa\u0107 na rysunku 4.\u00a0 W celu odzyskania fragment\u00f3w obrazu mo\u017cemy zastosowa\u0107 technik\u0119 inpaintingu. W tym celu mo\u017cemy zastosowa\u0107 funkcj\u0119 inpaint(). Aby funkcja mog\u0142a odzyska\u0107 piksele, kt\u00f3re zosta\u0142y usuni\u0119te, nale\u017cy wskaza\u0107 mask\u0119 reprezentuj\u0105c\u0105 piksele do odzyskania. Program, kt\u00f3ry wykorzystuje technik\u0119 inpaintingu przedstawiono na listingu 4. Funkcja inpaint przyj\u0105\u0107 mo\u017ce opcje odzyskiwania INPAINT_NS oraz INPAINT_TELEA. W uproszczeni, technika inpaintingu polega na uwzgl\u0119dnieniu kolor\u00f3w oraz tekstury na kraw\u0119dziach ubytku i wype\u0142nieniu miejsc obrazu z ubytkiem. Wynik po zastosowaniu inpaintingu zaprezentowano na rysunku 5.<\/p>\r\n&nbsp;\r\n\r\n[caption id=\"attachment_169\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix.jpg\" alt=\"\" class=\"wp-image-169 size-full\" width=\"640\" height=\"426\" \/> Rysunek 4. Przyk\u0142ad obrazu z zak\u0142\u00f3ceniami, ubytkami.[\/caption]\r\n<p style=\"text-align: justify\">Listing 4. Program prezentuj\u0105cy technik\u0119 inpaintingu.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nimport numpy as np\r\nimport cv2 as cv\r\n\r\nimg = cv.imread('owoce_mix.jpg')\r\nmask = cv.imread('owoce_maska_a.png',0)\r\nmask2 = cv.bitwise_not(mask)\r\n\r\ndst = cv.inpaint(img,mask2,3,cv.INPAINT_TELEA)\r\n\r\ncv.imwrite('owoce_odtworzony.jpg',dst);\r\n\r\ncv.imshow('dst',dst)\r\ncv.waitKey(0)\r\ncv.destroyAllWindows()\r\n\r\n[\/code]\r\n\r\n[caption id=\"attachment_173\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony.jpg\" alt=\"\" class=\"size-full wp-image-173\" width=\"640\" height=\"426\" \/> Rysunek 5. Obraz po odtworzeniu.[\/caption]\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_175\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b.jpg\" alt=\"\" class=\"wp-image-175 size-full\" width=\"640\" height=\"426\" \/> Rysunek 6. Obraz z du\u017cym ubytkiem.[\/caption]\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_176\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b.jpg\" alt=\"\" class=\"wp-image-176 size-full\" width=\"640\" height=\"426\" \/> Rysunek 7. Pr\u00f3ba odtworzenia obrazu z zastosowaniem techniki inpaintingu.[\/caption]\r\n<p style=\"text-align: justify\">Cz\u0119\u015b\u0107 operacji na obrazie to operacje polegaj\u0105ce na <strong>filtracji obraz\u00f3w<\/strong>. Filtr to algorytm kt\u00f3ry pewien obraz I(x,y) przekszta\u0142ca w obraz I'(x,y) poprzez obliczanie dla ka\u017cdego piksela x,y w I' pewnej funkcji pikseli z I, kt\u00f3re znajduj\u0105 si\u0119 w niewielkim obszarze wok\u00f3\u0142 tego punktu (x,y). Szablon kt\u00f3ry definiuje ten obszar i spos\u00f3b post\u0119powania nazywamy <strong>filtrem<\/strong> albo <strong>j\u0105drem<\/strong>. Ka\u017cdy filtr liniowy mo\u017cemy opisa\u0107 <strong>operacj\u0105 splotu<\/strong>. Oczywi\u015bcie kluczem pozostaje dobranie poszczeg\u00f3lnych <strong>wag filtra<\/strong>. Ka\u017cde z j\u0105der ma jedn\u0105 warto\u015b\u0107, tzw. punkt centralny, kt\u00f3ry okre\u015bla spos\u00f3b po\u0142o\u017cenia j\u0105dra wzgl\u0119dem obrazu \u017ar\u00f3d\u0142owego. W trakcie stosowania filtr\u00f3w pojawia si\u0119 pewna kwestia jak post\u0119powa\u0107 z pikslami na kraw\u0119dzi obrazu. W przypadku biblioteki OpenCV tworzone s\u0105 wirtualne kraw\u0119dzie.<\/p>\r\n<p style=\"text-align: justify\">Wa\u017cn\u0105 operacj\u0105 jest <strong>progowanie<\/strong>, obszar\u00f3w obrazu. W zadaniu tym chcemy progowa\u0107 pewne warto\u015bci pikseli. Na listingu 5 przedstawiono program, kt\u00f3ry dokonuje progowania obrazu wej\u015bciowego dla progu 100, 150 oraz 127. W zadaniu progowania mo\u017cemy wykorzysta\u0107 funkcj\u0119 treshold(). Funkcja mo\u017ce progowa\u0107 obraz na kilka spos\u00f3b\u00f3w: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC\u00a0 .<\/p>\r\n<p style=\"text-align: justify\">Listing 5. Program prezentuj\u0105cy r\u00f3\u017cne rodzaje progowania.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('obraz_szary.jpg',0)\r\n\r\nret1,th1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)\r\nret2,th2 = cv2.threshold(img,100,255,cv2.THRESH_BINARY_INV)\r\nret3,th3 = cv2.threshold(img,150,255,cv2.THRESH_TRUNC)\r\nret4,th4 = cv2.threshold(img,150,255,cv2.THRESH_TOZERO)\r\nret5,th5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)\r\n\r\nplt.subplot(2,3,1),\r\nplt.imshow(img,'gray')\r\nplt.title('Obraz wejsciowy');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.subplot(2,3,2),\r\nplt.imshow(th1,'gray')\r\nplt.title('THRESH_BINARY');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.subplot(2,3,3),\r\nplt.imshow(th2,'gray')\r\nplt.title('THRESH_BINARY_INV');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.subplot(2,3,4),\r\nplt.imshow(th3,'gray')\r\nplt.title('THRESH_TRUNC');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.subplot(2,3,5),\r\nplt.imshow(th4,'gray')\r\nplt.title('THRESH_TOZERO');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.subplot(2,3,6),\r\nplt.imshow(th5,'gray')\r\nplt.title('THRESH_TOZERO_INV');\r\nplt.xticks([]), plt.yticks([])\r\n\r\nplt.show()\r\n[\/code]\r\n\r\n[caption id=\"attachment_200\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png\" alt=\"\" class=\"wp-image-200 size-full\" width=\"640\" height=\"437\" \/> Rysunek 9. Wynik dzia\u0142ania filtracji obrazu.[\/caption]\r\n<p style=\"text-align: justify\">Inn\u0105 metod\u0105 progowania jest metoda Otsu. Metoda Ostu sprawdza wszystkie warto\u015bci graniczne i oblicza wariacj\u0119 dla ka\u017cdej z klas pikseli poni\u017cej i powy\u017cej progu. Nast\u0119pnie dobiera pr\u00f3g tak aby zminimalizowa\u0107 sum\u0119 wariancji dla poszczeg\u00f3lnych klas. Aby zastosowa\u0107 t\u0105 metod\u0119 nale\u017cy zastosowa\u0107 opcj\u0119 TRESH_OTSU. Opr\u00f3cz powy\u017cszych metod istnieje jeszcze adaptacyjna technika progowania. Do tego celu nale\u017cy wykorzysta\u0107 funkcj\u0119 adaptiveTreshold().\u00a0 Funkcja dostraja pr\u00f3g w zale\u017cno\u015bci od wybranego obszaru rejonu. Dla ka\u017cdego obszaru liczona jest \u015brednia wa\u017cona (TRESH_MEAN_C) lub odleg\u0142o\u015b\u0107 w rozk\u0142adzie Gaussa od punktu centralnego (ADAPTIVE_TRESH_GAUSSIAN_C).<\/p>\r\n<p style=\"text-align: justify\">Wa\u017cnym elementem przetwarzania obraz\u00f3w s\u0105 <strong>filtry wyg\u0142adzaj\u0105ce<\/strong> i rozmywaj\u0105ce obraz. Najcz\u0119\u015bciej maj\u0105 znaczenie w przypadku redukcji szum\u00f3w lub artefakt\u00f3w aparatu fotograficznego\/kamery. W tym celu mo\u017cemy wykorzysta\u0107 funkcj\u0119 blur(), s\u0142u\u017c\u0105c\u0105 do rozmycia. Piksel na wyj\u015bciu jest \u015bredni\u0105 pikseli w wybranym oknie. Rozmazanie jest pewn\u0105 wersj\u0105 filtra prostok\u0105tnego. Opr\u00f3cz filtra u u\u015bredniaj\u0105cego mo\u017cemy zastosowa\u0107 filtr medianowy, w tym celu mo\u017cemy wykorzysta\u0107 funkcj\u0119 medianBlur(). W praktyce, bardzo cz\u0119sto wykorzystujemy filtr Gaussa. Filtrowanie polega na obliczeniu splotu dla ka\u017cdego piksela w tablicy wej\u015bciowej z znormalizowanym j\u0105drem gaussowskim - funkcja GaussianBlur(). Innym rodzajem filtra jest filtr bileteralny. Filtr ten s\u0142u\u017cy do wyg\u0142adzania z zachowaniem kraw\u0119dzi. Wa\u017cnym elementem wp\u0142ywaj\u0105cym na skuteczno\u015b\u0107 filtracji oraz uzyskane efekty s\u0105 szczeg\u00f3\u0142owe parametry poszczeg\u00f3lnych funkcji. W wielu przypadkach, skuteczno\u015b\u0107 mo\u017cemy por\u00f3wna\u0107 poprzez sprawdzenie dzia\u0142ania funkcji dla kilku\/kilkunastu parametr\u00f3w.<\/p>\r\n<p style=\"text-align: justify\">Listing 6. Program prezentuj\u0105cy dzia\u0142anie r\u00f3\u017cne rodzaje filtr\u00f3w.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('cat.jpg')\r\n\r\ncv2.imshow('oryginal',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\nkernel = np.ones((5,5),np.float32)\/25\r\ndst = cv2.filter2D(img,-1,kernel)\r\n\r\ncv2.imshow('dst',dst)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('1_filtr.png',dst);\r\n\r\nblur = cv2.GaussianBlur(img,(25,5),0)\r\ncv2.imshow('blur',blur)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('2_filtr.png',blur);\r\n\r\nmedian = cv2.medianBlur(img,21)\r\ncv2.imshow('median',median)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('3_filtr.png',median);\r\n\r\n[\/code]\r\n\r\n<p style=\"text-align: justify\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat.jpg\" alt=\"\" class=\"size-full wp-image-199 aligncenter\" width=\"640\" height=\"437\" \/><\/p>\r\n\r\n\r\n[caption id=\"attachment_200\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png\" alt=\"\" class=\"wp-image-200 size-full\" width=\"640\" height=\"437\" \/> Rysunek 9. Wynik dzia\u0142ania filtracji obrazu.[\/caption]\r\n<p style=\"text-align: justify\">Opr\u00f3cz filtr\u00f3w dolnoprzepustowych - wyg\u0142adzaj\u0105cych mo\u017cemy stosowa\u0107 <strong>filtry g\u00f3rnoprzepustowe<\/strong>. Najcz\u0119\u015bciej filtry te s\u0142u\u017c\u0105 do wykrywania kraw\u0119dzi na obrazie. W zadaniu filtracji mo\u017cemy wykorzysta\u0107 filtr Sobela - funkcja Sobel; filtr Sharra oraz Laplace'a - funkcja Laplacian();<\/p>\r\n&nbsp;\r\n\r\nListing 7. Zastosowanie filtr\u00f3w g\u00f3rnoprzepustowych.\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('sudoku.jpg',0)\r\n\r\nlaplacian = cv2.Laplacian(img,cv2.CV_64F)\r\nsobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)\r\nsobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)\r\n\r\nplt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')\r\nplt.title('Original'), plt.xticks([]), plt.yticks([])\r\nplt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')\r\nplt.title('Laplacian'), plt.xticks([]), plt.yticks([])\r\nplt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')\r\nplt.title('Sobel X'), plt.xticks([]), plt.yticks([])\r\nplt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')\r\nplt.title('Sobel Y'), plt.xticks([]), plt.yticks([])\r\n\r\nplt.show()\r\n\r\n[\/code]\r\n\r\n[caption id=\"attachment_208\" align=\"alignnone\" width=\"850\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1.png\" alt=\"\" class=\"wp-image-208 size-full\" width=\"850\" height=\"721\" \/> Rysunek 10. Przyk\u0142ad zastosowania metod wykrywania kraw\u0119dzi.[\/caption]\r\n<p style=\"text-align: justify\">Wa\u017cnym aspektem przetwarzania obraz\u00f3w s\u0105 <strong>przekszta\u0142cenia morfologiczne<\/strong>. Zasadniczo wszystkie operacje bazuj\u0105 na dw\u00f3ch podstawowych dzia\u0142aniach zwanych <strong>dylatacj\u0105<\/strong> i <strong>erozj\u0105<\/strong>. Operacje te s\u0105 wykorzystywane do usuwania szumu oraz ekstrakcji indywidualnych element\u00f3w oraz \u0142\u0105czenia rozdzielonych element\u00f3w obrazu. Dylacja to pewnego rodzaju splot, w kt\u00f3rym ka\u017cdy piksel jest zamieniany na lokalne maksimum wszystkich pikseli obejmuj\u0105cych dane j\u0105dro. Dylatacji powoduje, \u017ce obszary rozrastaj\u0105 si\u0119. Operacja erozji, jest operacj\u0105 odwrotn\u0105 do dylatacji.\u00a0 W trakcie dzia\u0142ania operacji erozji wykonywany jest splot, w kt\u00f3rym ka\u017cdy piksel jest zamieniany na lokalne minimum wszystkich pikseli obejmuj\u0105cych dane j\u0105dro. Efektem operacji erozji jest pomniejszenie obszaru. Operacje erozji oraz dylatacji mo\u017cemy wykona\u0107 kilkukrotnie poprzez ustawienie opcji iterations. Na listingu 9 zaprezentowano przyk\u0142ad operacji erozji dla obrazu prezentuj\u0105cego bia\u0142y znak na czarnym tle.<\/p>\r\nListing 8. Program prezentuj\u0105cy operacj\u0119 dylatacji\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\ndilation = cv2.dilate(img,kernel,iterations = 1)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('po dylatacji',dilation)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_dylatacji.png',dilation);\r\n\r\n[\/code]\r\n\r\n<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j.png\" alt=\"\" class=\"wp-image-212 size-full aligncenter\" width=\"112\" height=\"150\" \/>\r\n\r\n[caption id=\"attachment_213\" align=\"aligncenter\" width=\"112\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji.png\" alt=\"\" class=\"wp-image-213 size-full\" width=\"112\" height=\"150\" \/> Rysunek 11. Obraz po zastosowaniu operacji dylatacji.[\/caption]\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_214\" align=\"aligncenter\" width=\"112\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji_2.png\" alt=\"\" class=\"wp-image-214 size-full\" width=\"112\" height=\"150\" \/> Rysunek 12. Obraz po zastosowaniu operatora dylatacji dwukrotnie.[\/caption]\r\n\r\n&nbsp;\r\n\r\nListing 9. Program prezentuj\u0105cy operacj\u0119 dylatacji\r\n\r\n[code lang=\"python\"]\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nerosion = cv2.erode(img,kernel,iterations = 2)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('erozja',erosion)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_erozji_2.png',erosion);\r\n\r\n[\/code]\r\n\r\n[caption id=\"attachment_216\" align=\"aligncenter\" width=\"112\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_1.png\" alt=\"\" class=\"wp-image-216 size-full\" width=\"112\" height=\"150\" \/> Rysunek 13. Obraz po zastosowaniu operatora erozji.[\/caption]\r\n\r\n[caption id=\"attachment_217\" align=\"aligncenter\" width=\"112\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_2.png\" alt=\"\" class=\"wp-image-217 size-full\" width=\"112\" height=\"150\" \/> Rysunek 14. Obraz po zastosowaniu operatora erozji dwukrotnie.[\/caption]\r\n<p style=\"text-align: justify\">Bazuj\u0105c na tych dw\u00f3ch podstawowych operacjach mo\u017cemy tworzy\u0107 bardziej zaawansowane operacje morfologiczne takie jak <strong>otwieranie<\/strong> oraz <strong>zamykanie<\/strong>. Do zastosowania operacji mo\u017cemy wykorzysta\u0107 funkcj\u0119 morphologyEX. Otwieranie stosuje si\u0119 mi\u0119dzy innymi w przypadku policzenia obszar\u00f3w na obszarze logicznym. Technik\u0119 zamykania wykorzystuje si\u0119 w bardziej zaawansowanych algorytmach przetwarzaj\u0105cych po\u0142\u0105czone komponenty w celu redukcji niechcianych lub zawieraj\u0105cych szum fragment\u00f3w.<\/p>\r\n&nbsp;\r\n\r\nListing 10. Zastosowanie operacji zamkni\u0119cia.\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j_closing.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nclosing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('closing',closing)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_zamknieciu.png',closing);\r\n\r\n[\/code]\r\n\r\nListing 11. Zastosowanie operacji otwarcia.\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j_open.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nopening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('opening',opening)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_otwarciu_2.png',opening);\r\n\r\n[\/code]\r\n\r\n<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_zamknieciu.png\" alt=\"\" class=\"aligncenter wp-image-228 size-full\" width=\"112\" height=\"150\" \/>\r\n\r\n<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_closing.png\" alt=\"\" class=\"alignnone size-full wp-image-225 aligncenter\" width=\"112\" height=\"150\" \/> <img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_open.png\" alt=\"\" class=\"alignnone size-full wp-image-226 aligncenter\" width=\"112\" height=\"150\" \/> <img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_otwarciu_2.png\" alt=\"\" class=\"alignnone size-full wp-image-227 aligncenter\" width=\"112\" height=\"150\" \/>\r\n<p style=\"text-align: center\">Rysunek 15. Wyniki operacji otwarcia.<\/p>\r\n<p style=\"text-align: justify\">Wa\u017cnym aspektem przetwarzania obraz\u00f3w mo\u017ce by\u0107 <strong>wyr\u00f3wnanie histogramu<\/strong>. Histogram opisuje rozk\u0142ad poziom\u00f3w jasno\u015bci w obrazie. Mo\u017ce si\u0119 zdarzy\u0107, \u017ce uk\u0142ad optyczny lub matryca nie poradz\u0105 sobie z uchwyceniem interesuj\u0105cych nas poziom\u00f3w jasno\u015bci. Pom\u00f3c mo\u017ce wyr\u00f3wnanie histogramu. Polega ono na tym, aby wyst\u0119puj\u0105ce w zarejestrowanym obrazie odcienie jasno\u015bci obrazu, przeskalowa\u0107\/przekszta\u0142ci\u0107 tak aby mie\u015bci\u0142y si\u0119 w ca\u0142ym zakresie 0-255. Biblioteka OpenCV posiada funkcj\u0119\u00a0 equalizeHist() kt\u00f3a umo\u017cliwia automatyczne wyr\u00f3wnanie histohramu. Na listingu 12 zaprezentowano program wyr\u00f3wnuj\u0105cy histogram zaj\u0119cia. Na Rysunku 16 zaprezentowano zdj\u0119cie przed i po zastosowaniu operacji wyr\u00f3wnania histogramu.<\/p>\r\nListing 12. Przyk\u0142ad wyr\u00f3wnania histogramu.\r\n\r\n[code lang=\"python\"]\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('krajobraz_hist.jpg',0)\r\n\r\nhist,bins = np.histogram(img.flatten(),256,[0,256])\r\n\r\ncdf = hist.cumsum()\r\ncdf_normalized = cdf * hist.max()\/ cdf.max()\r\n\r\nplt.plot(cdf_normalized, color = 'b')\r\nplt.hist(img.flatten(),256,[0,256], color = 'r')\r\nplt.xlim([0,256])\r\nplt.legend(('cdf','histogram'), loc = 'upper left')\r\nplt.show()\r\n\r\nimg = cv2.imread('krajobraz_hist.jpg',0)\r\nequ = cv2.equalizeHist(img)\r\nres = np.hstack((img,equ)) \r\ncv2.imwrite('res.png',res)\r\n\r\n[\/code]\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_293\" align=\"alignnone\" width=\"1280\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res.jpg\" alt=\"\" class=\"wp-image-293 size-full\" width=\"1280\" height=\"400\" \/> Rysunek 16. Przyk\u0142ad wyr\u00f3wnania histogramu.[\/caption]\r\n\r\n<strong>Zadanie 1.<\/strong>\r\n<p style=\"text-align: justify\">Dla zdj\u0119cia zaprezentowanego na rysunku 17, prosz\u0119 zaproponowa\u0107 seri\u0119 przekszta\u0142ce\u0144 obrazu, kt\u00f3re w wyniku kt\u00f3rego otrzymamy obraz tablicy rejestracyjnej zaprezentowanej na rysunku 18.<\/p>\r\n&nbsp;\r\n\r\n[caption id=\"attachment_232\" align=\"aligncenter\" width=\"640\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej.jpg\" alt=\"\" class=\"wp-image-232 size-full\" width=\"640\" height=\"426\" \/> Rysunek 17. Obraz wej\u015bciowy.[\/caption]\r\n\r\n[caption id=\"attachment_231\" align=\"aligncenter\" width=\"188\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/wynik_tablica.png\" alt=\"\" class=\"wp-image-231 size-full\" width=\"188\" height=\"61\" \/> Rysunek 18. Obraz wyj\u015bciowy.[\/caption]\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n<strong>Odpowied\u017a 1.<\/strong>\r\n\r\nNale\u017cy zastosowa\u0107 transformacje afiniczn\u0105, zmian\u0119 perepektywy, obrotu. W tym celu wykorzystujemy funkcje: getAffineTransform, warpAffine, getRotationMatrix2D, warpPerspective. Nale\u017cy dobra\u0107 odpowiednio paremetry funkcji. Na otrzymane rezultaty, mo\u017ce mie\u0107 wp\u0142yw kolejno\u015b\u0107 wykonywania przekszta\u0142ce\u0144.\r\n\r\n&nbsp;\r\n\r\n<strong>Zadanie 2.<\/strong>\r\n\r\nWybierz kilka r\u00f3\u017cnorodnych obraz\u00f3w takich jak: krajobraz, twarz, stare uszkodzone zdj\u0119cie. Nast\u0119pnie przygotuj maski i spr\u00f3buj odzyska\u0107 framgenty uszkodzonych zdj\u0119\u0107 z wykorzystaniem techniki inpaintingu. Zwr\u00f3\u0107 uwag\u0119, czy na jako\u015bc odzyskanego zdj\u0119cia wp\u0142ywa jednorodno\u015b\u0107 struktury obrazu.\r\n\r\n<strong>Odpowied\u017a 2.<\/strong>\r\n\r\nNa listingu 13 zaprezentowano fragment programu wykorzystuj\u0105cy technik\u0119 inpaintingu.\r\n\r\n[code lang=\"python\"] \r\nimport numpy as np \r\nimport cv2 as cv \r\nimg = cv.imread('zdjecie_uszkodzone.jpg')\r\nmask = cv.imread('maska_dla_zdjecia.png',0)\r\nmask2 = cv.bitwise_not(mask) \r\ndst = cv.inpaint(img,mask2,3,cv.INPAINT_TELEA) \r\ncv.imwrite('obraz_odtworzony.jpg',dst); \r\ncv.imshow('dst',dst) \r\ncv.waitKey(0) \r\ncv.destroyAllWindows() \r\n[\/code]\r\n\r\n&nbsp;\r\n\r\n<strong>Zadanie 3.<\/strong>\r\n\r\nSprawd\u017a jak wp\u0142ywa wielko\u015b\u0107 maski, jego rozmiar na wyniki filtracji. W tym celu wykorzystaj funkcj\u0119 filter2D. Przeprowad\u017a eksperymenty dla kilku obraz\u00f3w i kilku stworzonych przez sibie filtr\u00f3w.\r\n\r\n<strong>Odpowied\u017a 3.<\/strong>\r\n<p style=\"text-align: justify\">Aby stworzy\u0107 w\u0142asny filtr nale\u017cy wykorzysta\u0107 funkcj\u0119 filter2D. Przyk\u0142\u0105d stworzenia filtru o rozmawrze 15x2 przedstawiono na listingu 14.<\/p>\r\n\r\n\r\n[code lang=\"python\"]\r\n\r\nkernel = np.ones((15,2),np.float32)\/30\r\ndst = cv2.filter2D(img,-1,kernel)\r\n\r\n[\/code]\r\n\r\n<strong>Zadanie 4.<\/strong>\r\n\r\nDla obrazu otrzymanego w zadaniu 1, prosz\u0119 wykona\u0107 nast\u0119puj\u0105ce operacj\u0119: prosz\u0119 zwi\u0119kszy\u0107 rozdzielczo\u015b\u0107 obrazu, a nast\u0119pnie przetestowa\u0107 r\u00f3\u017cne metody prgowania w celu, stworzenia jak najlepszego obrazu tablicy rejestracyjnej.\r\n\r\n<strong>Odpowied\u017a 4.<\/strong>\r\n\r\nDo przeskalowania obrazu nale\u017cy wykorzysta\u0107 funkcj\u0119 resize(). Przyk\u0142\u0105d listingu sprawdzaj\u0105cego r\u00f3\u017cne metody progorania zaprezentowano na listingu 3.\r\n\r\n<strong>Zadanie 5.<\/strong>\r\n\r\nDla zarejestrowanego zdj\u0119cia (podejrzenie czerniaka), prosz\u0119 zaproponowa\u0107 metod\u0119 przetwarzania wst\u0119pnego, kt\u00f3ra stworzy mask\u0119 obszaru zawieraj\u0105cego podejrzane znami\u0119. Prosz\u0119 dobra\u0107 parametry poszczeg\u00f3lnych metod przetwarzania.\r\n\r\n[caption id=\"attachment_242\" align=\"aligncenter\" width=\"650\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak.jpg\" alt=\"\" class=\"wp-image-242 size-full\" width=\"650\" height=\"426\" \/> Rysunek 18. Obraz wej\u015bciowy, prezentuj\u0105cy czerniaka sk\u00f3ry.[\/caption]\r\n\r\n&nbsp;\r\n\r\n<strong>Odpowied\u017a 5.<\/strong>\r\n\r\nPropozycj\u0119 przetwarzania obrazu mo\u017ce obejmowa\u0107: wczytanie obrazu w odciecniach szaro\u015bci, progowanie metod\u0105 Otsu a nast\u0119pnie wykonanie erzozji. Na listingu 15 zaprezentowano program, prezentuj\u0105cy dzia\u0142anie szpozeg\u00f3lnych etap\u00f3w przetwarzania obraz\u00f3w.\r\n\r\nListing 15. Przyk\u0142ad programu do wyznaczania obszaru czerniaka.\r\n\r\n[code lang=\"python\"]\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('czerniak.jpg',0)\r\n\r\nblur = cv2.GaussianBlur(img,(5,5),0)\r\nret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('th3',th3)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('po_progowaniu_otsu.png',th3);\r\n\r\nkernel = np.ones((5,5),np.uint8)\r\nerosion = cv2.erode(th3,kernel,iterations = 2)\r\n\r\ncv2.imshow('po erozji',erosion)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('po_erozji_czerniak_2.png',erosion);\r\n\r\n[\/code]\r\n\r\n<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu.png\" alt=\"\" class=\"size-full wp-image-244 aligncenter\" width=\"650\" height=\"426\" \/>\r\n\r\n&nbsp;\r\n\r\n[caption id=\"attachment_243\" align=\"aligncenter\" width=\"650\"]<img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2.png\" alt=\"\" class=\"wp-image-243 size-full\" width=\"650\" height=\"426\" \/> Rysunek 19. Obraz wyj\u015bciowy prezentuj\u0105cy mask\u0119 obszaru zawieraj\u0105cy czerniaka.[\/caption]","rendered":"<p style=\"text-align: justify\">Zarejestrowany obraz mo\u017cemy podda\u0107 ca\u0142emu szeregowi przekszta\u0142ce\u0144. Jednym z rodzaj\u00f3w takich przekszta\u0142ce\u0144 s\u0105 <strong>transformacje afiniczne<\/strong>. Transformacje afiniczne mog\u0105 by\u0107 stosowane, gdy mamy obraz z <strong>obszarem zainteresowania (ROI)<\/strong>, kt\u00f3ry chcemy przekszta\u0142ci\u0107, albo gdy mamy list\u0119 punkt\u00f3w, dla kt\u00f3rych obliczy\u0107 wynik przekszta\u0142cenia. W praktyce, aby zastosowa\u0107 przekszta\u0142cenie musimy obliczy\u0107 macierz przekszta\u0142ce\u0144 M, kt\u00f3ra reprezentuje <strong>transformacj\u0119<\/strong>.<\/p>\n<p style=\"text-align: justify\">Pierwszym przyk\u0142adem jest mo\u017cliwo\u015b\u0107 przekszta\u0142cenia obrazu, na podstawie trzech punkt\u00f3w, kt\u00f3re chcemy transformowa\u0107. Do obliczenia macierzy M, na podstawie punkt\u00f3w s\u0142u\u017cy funkcja getAffineTransform(). Przyk\u0142ad programu stosuj\u0105cy transformacj\u0119 zaprezentowano na listingu 1. Na wej\u015bciu funkcji musimy zdefiniowa\u0107 wsp\u00f3\u0142rz\u0119dne trzech punkt\u00f3w przed i po transformacji. Do zastosowania transformacji s\u0142u\u017cy funkcja warpAffin(). Na wej\u015bciu funkcji podajemy obraz, kt\u00f3ry chcemy podda\u0107 transformacji, macierz M, oraz rozmiar wyj\u015bciowy obrazu.\u00a0 Dla obliczonej raz macierzy M mo\u017cemy przekszta\u0142ci\u0107 wiele obraz\u00f3w. Wz\u00f3r transformacji mo\u017cna opisa\u0107:\u00a0 dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23). Na rysunku 1 zaprezentowano wynik transformacji oraz obraz wej\u015bciowy. Dla u\u0142atwienia interpretacji dzia\u0142ania, zastosowano funkcj\u0119 matplotlib opisuj\u0105c\u0105 wiersze i kolumny obrazu. W celu prze\u0142\u0105czania miejsca wy\u015bwietlania z wykorzystaniem biblioteki matplotlib mo\u017cna wykorzysta\u0107 opcje: <code class=\"hljs language-perl\">%matplotlib qt oraz\u00a0<\/code><code class=\"hljs language-cpp\">%matplotlib <span class=\"hljs-keyword\">inline.<\/span><\/code><\/p>\n<p style=\"text-align: justify\">Listing 1. Zastosowanie transformacji afinicznej.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,ch = img.shape\r\n\r\npts1 = np.float32(&#x5b;&#x5b;50,50],&#x5b;200,50],&#x5b;50,200]])\r\npts2 = np.float32(&#x5b;&#x5b;10,100],&#x5b;200,50],&#x5b;100,250]])\r\n\r\nM = cv2.getAffineTransform(pts1,pts2)\r\ndst = cv2.warpAffine(img,M,(cols,rows))\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n<\/pre>\n<figure id=\"attachment_157\" aria-describedby=\"caption-attachment-157\" style=\"width: 1024px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-1024x524.png\" alt=\"\" class=\"wp-image-157 size-large\" width=\"1024\" height=\"524\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-1024x524.png 1024w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-300x154.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-768x393.png 768w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-1536x786.png 1536w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-65x33.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-225x115.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a-350x179.png 350w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/transformacja_a.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption id=\"caption-attachment-157\" class=\"wp-caption-text\">Rysunek 1. Wynik dzia\u0142ania transformacji afinicznej.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Kolejnym przekszta\u0142ceniem afinicznym jest obr\u00f3t. W tym przypadku do obliczenia macierzy M wykorzystujemy funkcj\u0119 getRotationMatrix2D(). Na listingu 2 zaprezentowano przyk\u0142ad dzia\u0142ania <strong>transformacji obrotu<\/strong>. Funkcja wymaga podania\u00a0 punktu wok\u00f3\u0142 kt\u00f3rego nast\u0105pi obr\u00f3t, k\u0105t obrotu oraz skal\u0119 obrazu wyj\u015bciowego. Dla zastosowanego przypadku macierz M= \u00a01.73648178e-01, 9.84807753e-01, -5.07058978e+01; -9.84807753e-01, 1.73648178e-01, 5.79571064e+02. Na rysunku 2 przedstawiono przyk\u0142ad rotacji obrazu.<\/p>\n<p style=\"text-align: justify\">Listing 2. Zastosowanie transformacji obrotu.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,b = img.shape\r\n\r\nM = cv2.getRotationMatrix2D((cols\/2,rows\/2),80,1)\r\ndst = cv2.warpAffine(img,M,(cols,rows))\r\n\r\ncv2.imshow('dst',dst)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('szachownica_obrot.png',dst);\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n\r\n<\/pre>\n<figure id=\"attachment_160\" aria-describedby=\"caption-attachment-160\" style=\"width: 1920px\" class=\"wp-caption alignnone\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a.png\" alt=\"\" class=\"wp-image-160 size-full\" width=\"1920\" height=\"983\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a.png 1920w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-300x154.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-1024x524.png 1024w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-768x393.png 768w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-1536x786.png 1536w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-65x33.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-225x115.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/obrot_a-350x179.png 350w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><figcaption id=\"caption-attachment-160\" class=\"wp-caption-text\">Rysunek 2. Przyk\u0142ad transformacji obrotu.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Innym rodzajem przekszta\u0142ce\u0144, s\u0105 <strong>transformacje perspektywy<\/strong>. W tym przypadku, do obliczenia macierzy M stosujemy funkcj\u0119 getPerspectiveTransform a do przekszta\u0142cenia funkcj\u0119 wrapPerspective. Nowe warto\u015bci obliczane s\u0105 z wykorzystaniem wzoru dst(x,y)=src((M11x+M12y+M13)\/(M31x+M32y+M33), (M21x+M22y+M23)\/(M31x+M32y+M33)). Przyk\u0142ad transformacji zaprezentowano na listingu 3. W przypadku zmiany perspektywy wymagane jest podanie czterech punkt\u00f3w. Wynik przyk\u0142adowej transformacji zmiany perspektywy zaprezentowano na rysunku 3.<\/p>\n<p style=\"text-align: justify\">Listing 3. Przyk\u0142ad transformacji perspektywy.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nimg = cv2.imread('szachownica.png')\r\nrows,cols,ch = img.shape\r\n\r\npts1 = np.float32(&#x5b;&#x5b;56,65],&#x5b;368,52],&#x5b;28,387],&#x5b;389,390]])\r\npts2 = np.float32(&#x5b;&#x5b;0,0],&#x5b;500,0],&#x5b;0,500],&#x5b;300,300]])\r\n\r\nM = cv2.getPerspectiveTransform(pts1,pts2)\r\n\r\ndst = cv2.warpPerspective(img,M,(300,300))\r\n\r\nplt.subplot(121),plt.imshow(img),plt.title('Input')\r\nplt.subplot(122),plt.imshow(dst),plt.title('Output')\r\nplt.show()\r\n\r\n<\/pre>\n<figure id=\"attachment_162\" aria-describedby=\"caption-attachment-162\" style=\"width: 1920px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a.png\" alt=\"\" class=\"wp-image-162 size-full\" width=\"1920\" height=\"983\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a.png 1920w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-300x154.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-1024x524.png 1024w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-768x393.png 768w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-1536x786.png 1536w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-65x33.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-225x115.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/perspektywa_a-350x179.png 350w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><figcaption id=\"caption-attachment-162\" class=\"wp-caption-text\">Rysunek 3. Przyk\u0142ad zmiany perspektywy.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Istniej\u0105 inne, bardziej zaawansowane transformacje. W tym celu mo\u017cemy wykorzysta\u0107 funkcje bibliotekiOpenCV. Dla przyk\u0142adu, funkcja cartToPolar() s\u0142u\u017cy do konwersji wsp\u00f3\u0142rz\u0119dnych kartezja\u0144skich na biegunowe, funkcja polarToCart() s\u0142u\u017cy do konwersji wsp\u00f3\u0142rz\u0119dnych biegunowych na kartezja\u0144skie. Funkcja logPolar() jest wykorzystywana do przekszta\u0142ce\u0144 logarytmiczno-biegunowych. Warto zwr\u00f3ci\u0107 uwag\u0119 na inn\u0105 funkcj\u0119 remap(), kt\u00f3ra umo\u017cliwia og\u00f3lne odwzorowanie obrazu.<\/p>\n<p style=\"text-align: justify\">W trakcie rejestracji obrazu, mo\u017ce si\u0119 zdarzy\u0107, \u017ce fragment obrazu jest niepoprawnie zarejestrowany. Je\u015bli taka sytuacja ma miejsce, a s\u0105 to niewielkie ubytki, mo\u017cemy zastosowa\u0107 <strong>technik\u0119 renowacji<\/strong> obraz\u00f3w znan\u0105 jako <strong>inpainting<\/strong>. Przyk\u0142ad takiego ubytku mo\u017cemy zaobserwowa\u0107 na rysunku 4.\u00a0 W celu odzyskania fragment\u00f3w obrazu mo\u017cemy zastosowa\u0107 technik\u0119 inpaintingu. W tym celu mo\u017cemy zastosowa\u0107 funkcj\u0119 inpaint(). Aby funkcja mog\u0142a odzyska\u0107 piksele, kt\u00f3re zosta\u0142y usuni\u0119te, nale\u017cy wskaza\u0107 mask\u0119 reprezentuj\u0105c\u0105 piksele do odzyskania. Program, kt\u00f3ry wykorzystuje technik\u0119 inpaintingu przedstawiono na listingu 4. Funkcja inpaint przyj\u0105\u0107 mo\u017ce opcje odzyskiwania INPAINT_NS oraz INPAINT_TELEA. W uproszczeni, technika inpaintingu polega na uwzgl\u0119dnieniu kolor\u00f3w oraz tekstury na kraw\u0119dziach ubytku i wype\u0142nieniu miejsc obrazu z ubytkiem. Wynik po zastosowaniu inpaintingu zaprezentowano na rysunku 5.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_169\" aria-describedby=\"caption-attachment-169\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix.jpg\" alt=\"\" class=\"wp-image-169 size-full\" width=\"640\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix-300x200.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix-225x150.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix-350x233.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-169\" class=\"wp-caption-text\">Rysunek 4. Przyk\u0142ad obrazu z zak\u0142\u00f3ceniami, ubytkami.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Listing 4. Program prezentuj\u0105cy technik\u0119 inpaintingu.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport numpy as np\r\nimport cv2 as cv\r\n\r\nimg = cv.imread('owoce_mix.jpg')\r\nmask = cv.imread('owoce_maska_a.png',0)\r\nmask2 = cv.bitwise_not(mask)\r\n\r\ndst = cv.inpaint(img,mask2,3,cv.INPAINT_TELEA)\r\n\r\ncv.imwrite('owoce_odtworzony.jpg',dst);\r\n\r\ncv.imshow('dst',dst)\r\ncv.waitKey(0)\r\ncv.destroyAllWindows()\r\n\r\n<\/pre>\n<figure id=\"attachment_173\" aria-describedby=\"caption-attachment-173\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony.jpg\" alt=\"\" class=\"size-full wp-image-173\" width=\"640\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony-300x200.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony-225x150.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony-350x233.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-173\" class=\"wp-caption-text\">Rysunek 5. Obraz po odtworzeniu.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_175\" aria-describedby=\"caption-attachment-175\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b.jpg\" alt=\"\" class=\"wp-image-175 size-full\" width=\"640\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b-300x200.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b-225x150.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_mix_b-350x233.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-175\" class=\"wp-caption-text\">Rysunek 6. Obraz z du\u017cym ubytkiem.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_176\" aria-describedby=\"caption-attachment-176\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b.jpg\" alt=\"\" class=\"wp-image-176 size-full\" width=\"640\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b-300x200.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b-225x150.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/owoce_odtworzony_b-350x233.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-176\" class=\"wp-caption-text\">Rysunek 7. Pr\u00f3ba odtworzenia obrazu z zastosowaniem techniki inpaintingu.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Cz\u0119\u015b\u0107 operacji na obrazie to operacje polegaj\u0105ce na <strong>filtracji obraz\u00f3w<\/strong>. Filtr to algorytm kt\u00f3ry pewien obraz I(x,y) przekszta\u0142ca w obraz I'(x,y) poprzez obliczanie dla ka\u017cdego piksela x,y w I&#8217; pewnej funkcji pikseli z I, kt\u00f3re znajduj\u0105 si\u0119 w niewielkim obszarze wok\u00f3\u0142 tego punktu (x,y). Szablon kt\u00f3ry definiuje ten obszar i spos\u00f3b post\u0119powania nazywamy <strong>filtrem<\/strong> albo <strong>j\u0105drem<\/strong>. Ka\u017cdy filtr liniowy mo\u017cemy opisa\u0107 <strong>operacj\u0105 splotu<\/strong>. Oczywi\u015bcie kluczem pozostaje dobranie poszczeg\u00f3lnych <strong>wag filtra<\/strong>. Ka\u017cde z j\u0105der ma jedn\u0105 warto\u015b\u0107, tzw. punkt centralny, kt\u00f3ry okre\u015bla spos\u00f3b po\u0142o\u017cenia j\u0105dra wzgl\u0119dem obrazu \u017ar\u00f3d\u0142owego. W trakcie stosowania filtr\u00f3w pojawia si\u0119 pewna kwestia jak post\u0119powa\u0107 z pikslami na kraw\u0119dzi obrazu. W przypadku biblioteki OpenCV tworzone s\u0105 wirtualne kraw\u0119dzie.<\/p>\n<p style=\"text-align: justify\">Wa\u017cn\u0105 operacj\u0105 jest <strong>progowanie<\/strong>, obszar\u00f3w obrazu. W zadaniu tym chcemy progowa\u0107 pewne warto\u015bci pikseli. Na listingu 5 przedstawiono program, kt\u00f3ry dokonuje progowania obrazu wej\u015bciowego dla progu 100, 150 oraz 127. W zadaniu progowania mo\u017cemy wykorzysta\u0107 funkcj\u0119 treshold(). Funkcja mo\u017ce progowa\u0107 obraz na kilka spos\u00f3b\u00f3w: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC\u00a0 .<\/p>\n<p style=\"text-align: justify\">Listing 5. Program prezentuj\u0105cy r\u00f3\u017cne rodzaje progowania.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('obraz_szary.jpg',0)\r\n\r\nret1,th1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)\r\nret2,th2 = cv2.threshold(img,100,255,cv2.THRESH_BINARY_INV)\r\nret3,th3 = cv2.threshold(img,150,255,cv2.THRESH_TRUNC)\r\nret4,th4 = cv2.threshold(img,150,255,cv2.THRESH_TOZERO)\r\nret5,th5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)\r\n\r\nplt.subplot(2,3,1),\r\nplt.imshow(img,'gray')\r\nplt.title('Obraz wejsciowy');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.subplot(2,3,2),\r\nplt.imshow(th1,'gray')\r\nplt.title('THRESH_BINARY');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.subplot(2,3,3),\r\nplt.imshow(th2,'gray')\r\nplt.title('THRESH_BINARY_INV');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.subplot(2,3,4),\r\nplt.imshow(th3,'gray')\r\nplt.title('THRESH_TRUNC');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.subplot(2,3,5),\r\nplt.imshow(th4,'gray')\r\nplt.title('THRESH_TOZERO');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.subplot(2,3,6),\r\nplt.imshow(th5,'gray')\r\nplt.title('THRESH_TOZERO_INV');\r\nplt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.show()\r\n<\/pre>\n<figure id=\"attachment_200\" aria-describedby=\"caption-attachment-200\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png\" alt=\"\" class=\"wp-image-200 size-full\" width=\"640\" height=\"437\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-300x205.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-65x44.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-225x154.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-350x239.png 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-200\" class=\"wp-caption-text\">Rysunek 9. Wynik dzia\u0142ania filtracji obrazu.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Inn\u0105 metod\u0105 progowania jest metoda Otsu. Metoda Ostu sprawdza wszystkie warto\u015bci graniczne i oblicza wariacj\u0119 dla ka\u017cdej z klas pikseli poni\u017cej i powy\u017cej progu. Nast\u0119pnie dobiera pr\u00f3g tak aby zminimalizowa\u0107 sum\u0119 wariancji dla poszczeg\u00f3lnych klas. Aby zastosowa\u0107 t\u0105 metod\u0119 nale\u017cy zastosowa\u0107 opcj\u0119 TRESH_OTSU. Opr\u00f3cz powy\u017cszych metod istnieje jeszcze adaptacyjna technika progowania. Do tego celu nale\u017cy wykorzysta\u0107 funkcj\u0119 adaptiveTreshold().\u00a0 Funkcja dostraja pr\u00f3g w zale\u017cno\u015bci od wybranego obszaru rejonu. Dla ka\u017cdego obszaru liczona jest \u015brednia wa\u017cona (TRESH_MEAN_C) lub odleg\u0142o\u015b\u0107 w rozk\u0142adzie Gaussa od punktu centralnego (ADAPTIVE_TRESH_GAUSSIAN_C).<\/p>\n<p style=\"text-align: justify\">Wa\u017cnym elementem przetwarzania obraz\u00f3w s\u0105 <strong>filtry wyg\u0142adzaj\u0105ce<\/strong> i rozmywaj\u0105ce obraz. Najcz\u0119\u015bciej maj\u0105 znaczenie w przypadku redukcji szum\u00f3w lub artefakt\u00f3w aparatu fotograficznego\/kamery. W tym celu mo\u017cemy wykorzysta\u0107 funkcj\u0119 blur(), s\u0142u\u017c\u0105c\u0105 do rozmycia. Piksel na wyj\u015bciu jest \u015bredni\u0105 pikseli w wybranym oknie. Rozmazanie jest pewn\u0105 wersj\u0105 filtra prostok\u0105tnego. Opr\u00f3cz filtra u u\u015bredniaj\u0105cego mo\u017cemy zastosowa\u0107 filtr medianowy, w tym celu mo\u017cemy wykorzysta\u0107 funkcj\u0119 medianBlur(). W praktyce, bardzo cz\u0119sto wykorzystujemy filtr Gaussa. Filtrowanie polega na obliczeniu splotu dla ka\u017cdego piksela w tablicy wej\u015bciowej z znormalizowanym j\u0105drem gaussowskim &#8211; funkcja GaussianBlur(). Innym rodzajem filtra jest filtr bileteralny. Filtr ten s\u0142u\u017cy do wyg\u0142adzania z zachowaniem kraw\u0119dzi. Wa\u017cnym elementem wp\u0142ywaj\u0105cym na skuteczno\u015b\u0107 filtracji oraz uzyskane efekty s\u0105 szczeg\u00f3\u0142owe parametry poszczeg\u00f3lnych funkcji. W wielu przypadkach, skuteczno\u015b\u0107 mo\u017cemy por\u00f3wna\u0107 poprzez sprawdzenie dzia\u0142ania funkcji dla kilku\/kilkunastu parametr\u00f3w.<\/p>\n<p style=\"text-align: justify\">Listing 6. Program prezentuj\u0105cy dzia\u0142anie r\u00f3\u017cne rodzaje filtr\u00f3w.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('cat.jpg')\r\n\r\ncv2.imshow('oryginal',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\nkernel = np.ones((5,5),np.float32)\/25\r\ndst = cv2.filter2D(img,-1,kernel)\r\n\r\ncv2.imshow('dst',dst)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('1_filtr.png',dst);\r\n\r\nblur = cv2.GaussianBlur(img,(25,5),0)\r\ncv2.imshow('blur',blur)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('2_filtr.png',blur);\r\n\r\nmedian = cv2.medianBlur(img,21)\r\ncv2.imshow('median',median)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('3_filtr.png',median);\r\n\r\n<\/pre>\n<p style=\"text-align: justify\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat.jpg\" alt=\"\" class=\"size-full wp-image-199 aligncenter\" width=\"640\" height=\"437\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat-300x205.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat-65x44.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat-225x154.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/cat-350x239.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/p>\n<figure id=\"attachment_200\" aria-describedby=\"caption-attachment-200\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png\" alt=\"\" class=\"wp-image-200 size-full\" width=\"640\" height=\"437\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr.png 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-300x205.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-65x44.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-225x154.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/3_filtr-350x239.png 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-200\" class=\"wp-caption-text\">Rysunek 9. Wynik dzia\u0142ania filtracji obrazu.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Opr\u00f3cz filtr\u00f3w dolnoprzepustowych &#8211; wyg\u0142adzaj\u0105cych mo\u017cemy stosowa\u0107 <strong>filtry g\u00f3rnoprzepustowe<\/strong>. Najcz\u0119\u015bciej filtry te s\u0142u\u017c\u0105 do wykrywania kraw\u0119dzi na obrazie. W zadaniu filtracji mo\u017cemy wykorzysta\u0107 filtr Sobela &#8211; funkcja Sobel; filtr Sharra oraz Laplace&#8217;a &#8211; funkcja Laplacian();<\/p>\n<p>&nbsp;<\/p>\n<p>Listing 7. Zastosowanie filtr\u00f3w g\u00f3rnoprzepustowych.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('sudoku.jpg',0)\r\n\r\nlaplacian = cv2.Laplacian(img,cv2.CV_64F)\r\nsobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)\r\nsobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)\r\n\r\nplt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')\r\nplt.title('Original'), plt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\nplt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')\r\nplt.title('Laplacian'), plt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\nplt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')\r\nplt.title('Sobel X'), plt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\nplt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')\r\nplt.title('Sobel Y'), plt.xticks(&#x5b;]), plt.yticks(&#x5b;])\r\n\r\nplt.show()\r\n\r\n<\/pre>\n<figure id=\"attachment_208\" aria-describedby=\"caption-attachment-208\" style=\"width: 850px\" class=\"wp-caption alignnone\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1.png\" alt=\"\" class=\"wp-image-208 size-full\" width=\"850\" height=\"721\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1.png 850w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1-300x254.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1-768x651.png 768w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1-65x55.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1-225x191.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/Figure_1-1-350x297.png 350w\" sizes=\"(max-width: 850px) 100vw, 850px\" \/><figcaption id=\"caption-attachment-208\" class=\"wp-caption-text\">Rysunek 10. Przyk\u0142ad zastosowania metod wykrywania kraw\u0119dzi.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Wa\u017cnym aspektem przetwarzania obraz\u00f3w s\u0105 <strong>przekszta\u0142cenia morfologiczne<\/strong>. Zasadniczo wszystkie operacje bazuj\u0105 na dw\u00f3ch podstawowych dzia\u0142aniach zwanych <strong>dylatacj\u0105<\/strong> i <strong>erozj\u0105<\/strong>. Operacje te s\u0105 wykorzystywane do usuwania szumu oraz ekstrakcji indywidualnych element\u00f3w oraz \u0142\u0105czenia rozdzielonych element\u00f3w obrazu. Dylacja to pewnego rodzaju splot, w kt\u00f3rym ka\u017cdy piksel jest zamieniany na lokalne maksimum wszystkich pikseli obejmuj\u0105cych dane j\u0105dro. Dylatacji powoduje, \u017ce obszary rozrastaj\u0105 si\u0119. Operacja erozji, jest operacj\u0105 odwrotn\u0105 do dylatacji.\u00a0 W trakcie dzia\u0142ania operacji erozji wykonywany jest splot, w kt\u00f3rym ka\u017cdy piksel jest zamieniany na lokalne minimum wszystkich pikseli obejmuj\u0105cych dane j\u0105dro. Efektem operacji erozji jest pomniejszenie obszaru. Operacje erozji oraz dylatacji mo\u017cemy wykona\u0107 kilkukrotnie poprzez ustawienie opcji iterations. Na listingu 9 zaprezentowano przyk\u0142ad operacji erozji dla obrazu prezentuj\u0105cego bia\u0142y znak na czarnym tle.<\/p>\n<p>Listing 8. Program prezentuj\u0105cy operacj\u0119 dylatacji<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\ndilation = cv2.dilate(img,kernel,iterations = 1)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('po dylatacji',dilation)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_dylatacji.png',dilation);\r\n\r\n<\/pre>\n<p><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j.png\" alt=\"\" class=\"wp-image-212 size-full aligncenter\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><\/p>\n<figure id=\"attachment_213\" aria-describedby=\"caption-attachment-213\" style=\"width: 112px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji.png\" alt=\"\" class=\"wp-image-213 size-full\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><figcaption id=\"caption-attachment-213\" class=\"wp-caption-text\">Rysunek 11. Obraz po zastosowaniu operacji dylatacji.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_214\" aria-describedby=\"caption-attachment-214\" style=\"width: 112px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji_2.png\" alt=\"\" class=\"wp-image-214 size-full\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji_2.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_dylatacji_2-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><figcaption id=\"caption-attachment-214\" class=\"wp-caption-text\">Rysunek 12. Obraz po zastosowaniu operatora dylatacji dwukrotnie.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>Listing 9. Program prezentuj\u0105cy operacj\u0119 dylatacji<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nerosion = cv2.erode(img,kernel,iterations = 2)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('erozja',erosion)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_erozji_2.png',erosion);\r\n\r\n<\/pre>\n<figure id=\"attachment_216\" aria-describedby=\"caption-attachment-216\" style=\"width: 112px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_1.png\" alt=\"\" class=\"wp-image-216 size-full\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_1.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_1-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><figcaption id=\"caption-attachment-216\" class=\"wp-caption-text\">Rysunek 13. Obraz po zastosowaniu operatora erozji.<\/figcaption><\/figure>\n<figure id=\"attachment_217\" aria-describedby=\"caption-attachment-217\" style=\"width: 112px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_2.png\" alt=\"\" class=\"wp-image-217 size-full\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_2.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_2-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><figcaption id=\"caption-attachment-217\" class=\"wp-caption-text\">Rysunek 14. Obraz po zastosowaniu operatora erozji dwukrotnie.<\/figcaption><\/figure>\n<p style=\"text-align: justify\">Bazuj\u0105c na tych dw\u00f3ch podstawowych operacjach mo\u017cemy tworzy\u0107 bardziej zaawansowane operacje morfologiczne takie jak <strong>otwieranie<\/strong> oraz <strong>zamykanie<\/strong>. Do zastosowania operacji mo\u017cemy wykorzysta\u0107 funkcj\u0119 morphologyEX. Otwieranie stosuje si\u0119 mi\u0119dzy innymi w przypadku policzenia obszar\u00f3w na obszarze logicznym. Technik\u0119 zamykania wykorzystuje si\u0119 w bardziej zaawansowanych algorytmach przetwarzaj\u0105cych po\u0142\u0105czone komponenty w celu redukcji niechcianych lub zawieraj\u0105cych szum fragment\u00f3w.<\/p>\n<p>&nbsp;<\/p>\n<p>Listing 10. Zastosowanie operacji zamkni\u0119cia.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j_closing.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nclosing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('closing',closing)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_zamknieciu.png',closing);\r\n\r\n<\/pre>\n<p>Listing 11. Zastosowanie operacji otwarcia.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\n\r\nimg = cv2.imread('j_open.png',0)\r\nkernel = np.ones((5,5),np.uint8)\r\nopening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('opening',opening)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imwrite('po_otwarciu_2.png',opening);\r\n\r\n<\/pre>\n<p><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_zamknieciu.png\" alt=\"\" class=\"aligncenter wp-image-228 size-full\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_zamknieciu.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_zamknieciu-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><\/p>\n<p><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_closing.png\" alt=\"\" class=\"alignnone size-full wp-image-225 aligncenter\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_closing.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_closing-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/> <img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_open.png\" alt=\"\" class=\"alignnone size-full wp-image-226 aligncenter\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_open.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/j_open-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/> <img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_otwarciu_2.png\" alt=\"\" class=\"alignnone size-full wp-image-227 aligncenter\" width=\"112\" height=\"150\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_otwarciu_2.png 112w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_otwarciu_2-65x87.png 65w\" sizes=\"(max-width: 112px) 100vw, 112px\" \/><\/p>\n<p style=\"text-align: center\">Rysunek 15. Wyniki operacji otwarcia.<\/p>\n<p style=\"text-align: justify\">Wa\u017cnym aspektem przetwarzania obraz\u00f3w mo\u017ce by\u0107 <strong>wyr\u00f3wnanie histogramu<\/strong>. Histogram opisuje rozk\u0142ad poziom\u00f3w jasno\u015bci w obrazie. Mo\u017ce si\u0119 zdarzy\u0107, \u017ce uk\u0142ad optyczny lub matryca nie poradz\u0105 sobie z uchwyceniem interesuj\u0105cych nas poziom\u00f3w jasno\u015bci. Pom\u00f3c mo\u017ce wyr\u00f3wnanie histogramu. Polega ono na tym, aby wyst\u0119puj\u0105ce w zarejestrowanym obrazie odcienie jasno\u015bci obrazu, przeskalowa\u0107\/przekszta\u0142ci\u0107 tak aby mie\u015bci\u0142y si\u0119 w ca\u0142ym zakresie 0-255. Biblioteka OpenCV posiada funkcj\u0119\u00a0 equalizeHist() kt\u00f3a umo\u017cliwia automatyczne wyr\u00f3wnanie histohramu. Na listingu 12 zaprezentowano program wyr\u00f3wnuj\u0105cy histogram zaj\u0119cia. Na Rysunku 16 zaprezentowano zdj\u0119cie przed i po zastosowaniu operacji wyr\u00f3wnania histogramu.<\/p>\n<p>Listing 12. Przyk\u0142ad wyr\u00f3wnania histogramu.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('krajobraz_hist.jpg',0)\r\n\r\nhist,bins = np.histogram(img.flatten(),256,&#x5b;0,256])\r\n\r\ncdf = hist.cumsum()\r\ncdf_normalized = cdf * hist.max()\/ cdf.max()\r\n\r\nplt.plot(cdf_normalized, color = 'b')\r\nplt.hist(img.flatten(),256,&#x5b;0,256], color = 'r')\r\nplt.xlim(&#x5b;0,256])\r\nplt.legend(('cdf','histogram'), loc = 'upper left')\r\nplt.show()\r\n\r\nimg = cv2.imread('krajobraz_hist.jpg',0)\r\nequ = cv2.equalizeHist(img)\r\nres = np.hstack((img,equ)) \r\ncv2.imwrite('res.png',res)\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_293\" aria-describedby=\"caption-attachment-293\" style=\"width: 1280px\" class=\"wp-caption alignnone\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res.jpg\" alt=\"\" class=\"wp-image-293 size-full\" width=\"1280\" height=\"400\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res.jpg 1280w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-300x94.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-1024x320.jpg 1024w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-768x240.jpg 768w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-65x20.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-225x70.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/res-350x109.jpg 350w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><figcaption id=\"caption-attachment-293\" class=\"wp-caption-text\">Rysunek 16. Przyk\u0142ad wyr\u00f3wnania histogramu.<\/figcaption><\/figure>\n<p><strong>Zadanie 1.<\/strong><\/p>\n<p style=\"text-align: justify\">Dla zdj\u0119cia zaprezentowanego na rysunku 17, prosz\u0119 zaproponowa\u0107 seri\u0119 przekszta\u0142ce\u0144 obrazu, kt\u00f3re w wyniku kt\u00f3rego otrzymamy obraz tablicy rejestracyjnej zaprezentowanej na rysunku 18.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_232\" aria-describedby=\"caption-attachment-232\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej.jpg\" alt=\"\" class=\"wp-image-232 size-full\" width=\"640\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej.jpg 640w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej-300x200.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej-225x150.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/auto_rej-350x233.jpg 350w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-232\" class=\"wp-caption-text\">Rysunek 17. Obraz wej\u015bciowy.<\/figcaption><\/figure>\n<figure id=\"attachment_231\" aria-describedby=\"caption-attachment-231\" style=\"width: 188px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/wynik_tablica.png\" alt=\"\" class=\"wp-image-231 size-full\" width=\"188\" height=\"61\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/wynik_tablica.png 188w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/wynik_tablica-65x21.png 65w\" sizes=\"(max-width: 188px) 100vw, 188px\" \/><figcaption id=\"caption-attachment-231\" class=\"wp-caption-text\">Rysunek 18. Obraz wyj\u015bciowy.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Odpowied\u017a 1.<\/strong><\/p>\n<p>Nale\u017cy zastosowa\u0107 transformacje afiniczn\u0105, zmian\u0119 perepektywy, obrotu. W tym celu wykorzystujemy funkcje: getAffineTransform, warpAffine, getRotationMatrix2D, warpPerspective. Nale\u017cy dobra\u0107 odpowiednio paremetry funkcji. Na otrzymane rezultaty, mo\u017ce mie\u0107 wp\u0142yw kolejno\u015b\u0107 wykonywania przekszta\u0142ce\u0144.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Zadanie 2.<\/strong><\/p>\n<p>Wybierz kilka r\u00f3\u017cnorodnych obraz\u00f3w takich jak: krajobraz, twarz, stare uszkodzone zdj\u0119cie. Nast\u0119pnie przygotuj maski i spr\u00f3buj odzyska\u0107 framgenty uszkodzonych zdj\u0119\u0107 z wykorzystaniem techniki inpaintingu. Zwr\u00f3\u0107 uwag\u0119, czy na jako\u015bc odzyskanego zdj\u0119cia wp\u0142ywa jednorodno\u015b\u0107 struktury obrazu.<\/p>\n<p><strong>Odpowied\u017a 2.<\/strong><\/p>\n<p>Na listingu 13 zaprezentowano fragment programu wykorzystuj\u0105cy technik\u0119 inpaintingu.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\"> \r\nimport numpy as np \r\nimport cv2 as cv \r\nimg = cv.imread('zdjecie_uszkodzone.jpg')\r\nmask = cv.imread('maska_dla_zdjecia.png',0)\r\nmask2 = cv.bitwise_not(mask) \r\ndst = cv.inpaint(img,mask2,3,cv.INPAINT_TELEA) \r\ncv.imwrite('obraz_odtworzony.jpg',dst); \r\ncv.imshow('dst',dst) \r\ncv.waitKey(0) \r\ncv.destroyAllWindows() \r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Zadanie 3.<\/strong><\/p>\n<p>Sprawd\u017a jak wp\u0142ywa wielko\u015b\u0107 maski, jego rozmiar na wyniki filtracji. W tym celu wykorzystaj funkcj\u0119 filter2D. Przeprowad\u017a eksperymenty dla kilku obraz\u00f3w i kilku stworzonych przez sibie filtr\u00f3w.<\/p>\n<p><strong>Odpowied\u017a 3.<\/strong><\/p>\n<p style=\"text-align: justify\">Aby stworzy\u0107 w\u0142asny filtr nale\u017cy wykorzysta\u0107 funkcj\u0119 filter2D. Przyk\u0142\u0105d stworzenia filtru o rozmawrze 15&#215;2 przedstawiono na listingu 14.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n\r\nkernel = np.ones((15,2),np.float32)\/30\r\ndst = cv2.filter2D(img,-1,kernel)\r\n\r\n<\/pre>\n<p><strong>Zadanie 4.<\/strong><\/p>\n<p>Dla obrazu otrzymanego w zadaniu 1, prosz\u0119 wykona\u0107 nast\u0119puj\u0105ce operacj\u0119: prosz\u0119 zwi\u0119kszy\u0107 rozdzielczo\u015b\u0107 obrazu, a nast\u0119pnie przetestowa\u0107 r\u00f3\u017cne metody prgowania w celu, stworzenia jak najlepszego obrazu tablicy rejestracyjnej.<\/p>\n<p><strong>Odpowied\u017a 4.<\/strong><\/p>\n<p>Do przeskalowania obrazu nale\u017cy wykorzysta\u0107 funkcj\u0119 resize(). Przyk\u0142\u0105d listingu sprawdzaj\u0105cego r\u00f3\u017cne metody progorania zaprezentowano na listingu 3.<\/p>\n<p><strong>Zadanie 5.<\/strong><\/p>\n<p>Dla zarejestrowanego zdj\u0119cia (podejrzenie czerniaka), prosz\u0119 zaproponowa\u0107 metod\u0119 przetwarzania wst\u0119pnego, kt\u00f3ra stworzy mask\u0119 obszaru zawieraj\u0105cego podejrzane znami\u0119. Prosz\u0119 dobra\u0107 parametry poszczeg\u00f3lnych metod przetwarzania.<\/p>\n<figure id=\"attachment_242\" aria-describedby=\"caption-attachment-242\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak.jpg\" alt=\"\" class=\"wp-image-242 size-full\" width=\"650\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak.jpg 650w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak-300x197.jpg 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak-65x43.jpg 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak-225x147.jpg 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/czerniak-350x229.jpg 350w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><figcaption id=\"caption-attachment-242\" class=\"wp-caption-text\">Rysunek 18. Obraz wej\u015bciowy, prezentuj\u0105cy czerniaka sk\u00f3ry.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p><strong>Odpowied\u017a 5.<\/strong><\/p>\n<p>Propozycj\u0119 przetwarzania obrazu mo\u017ce obejmowa\u0107: wczytanie obrazu w odciecniach szaro\u015bci, progowanie metod\u0105 Otsu a nast\u0119pnie wykonanie erzozji. Na listingu 15 zaprezentowano program, prezentuj\u0105cy dzia\u0142anie szpozeg\u00f3lnych etap\u00f3w przetwarzania obraz\u00f3w.<\/p>\n<p>Listing 15. Przyk\u0142ad programu do wyznaczania obszaru czerniaka.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport cv2\r\nimport numpy as np\r\nfrom matplotlib import pyplot as plt\r\n\r\nimg = cv2.imread('czerniak.jpg',0)\r\n\r\nblur = cv2.GaussianBlur(img,(5,5),0)\r\nret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)\r\n\r\ncv2.imshow('oryg',img)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\n\r\ncv2.imshow('th3',th3)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('po_progowaniu_otsu.png',th3);\r\n\r\nkernel = np.ones((5,5),np.uint8)\r\nerosion = cv2.erode(th3,kernel,iterations = 2)\r\n\r\ncv2.imshow('po erozji',erosion)\r\ncv2.waitKey(0)\r\ncv2.destroyAllWindows()\r\ncv2.imwrite('po_erozji_czerniak_2.png',erosion);\r\n\r\n<\/pre>\n<p><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu.png\" alt=\"\" class=\"size-full wp-image-244 aligncenter\" width=\"650\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu.png 650w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu-300x197.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu-65x43.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu-225x147.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_progowaniu_otsu-350x229.png 350w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_243\" aria-describedby=\"caption-attachment-243\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><img src=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2.png\" alt=\"\" class=\"wp-image-243 size-full\" width=\"650\" height=\"426\" srcset=\"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2.png 650w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2-300x197.png 300w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2-65x43.png 65w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2-225x147.png 225w, http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-content\/uploads\/sites\/53\/2022\/07\/po_erozji_czerniak_2-350x229.png 350w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><figcaption id=\"caption-attachment-243\" class=\"wp-caption-text\">Rysunek 19. Obraz wyj\u015bciowy prezentuj\u0105cy mask\u0119 obszaru zawieraj\u0105cy czerniaka.<\/figcaption><\/figure>\n","protected":false},"author":49,"menu_order":3,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"part":3,"_links":{"self":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapters\/112"}],"collection":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/wp\/v2\/users\/49"}],"version-history":[{"count":97,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapters\/112\/revisions"}],"predecessor-version":[{"id":505,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapters\/112\/revisions\/505"}],"part":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapters\/112\/metadata\/"}],"wp:attachment":[{"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/wp\/v2\/media?parent=112"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/pressbooks\/v2\/chapter-type?post=112"},{"taxonomy":"contributor","embeddable":true,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/wp\/v2\/contributor?post=112"},{"taxonomy":"license","embeddable":true,"href":"http:\/\/pb.ee.pw.edu.pl\/pb\/psw\/wp-json\/wp\/v2\/license?post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}