# Python學習筆記 0006 (圖像轉正、鼠標打點) ## 建立數組、打點 ```javascript= import cv2 import numpy as np img = cv2.imread("img2.jpg") pts1 = np.int32 ([[978, 404],[1907, 80],[1025, 593],[1916, 365]])//設定一個32位元的正整數 print(pts1) print(pts1[0][0],pts1[0][1]) cv2.circle(img, (int(pts1[x][0]), int(pts1[x][1])), 10 ,(0 , 0 , 255), cv2.FILLED) cv2.imshow("img", img) cv2.waitKey(0) ``` - (int(pts1[x][0]), int(pts1[x][1])) 這裡需要用正整數 [[ 978. 404.] [1907. 80.] [1025. 593.] [1916. 365.]] 978 404 ![](https://i.imgur.com/CX03WFw.jpg) ## 用for迴圈 自動讀取打點 ```javascript= import cv2 import numpy as np img = cv2.imread("img2.jpg") pts1 = np.float32 ([[978, 404],[1450, 210],[1025, 593],[1530, 480]]) for x in range (0,4): cv2.circle(img, (int(pts1[x][0]), int(pts1[x][1])), 5 ,(0 , 0 , 255), cv2.FILLED) cv2.imshow("img", img) cv2.waitKey(0) ``` ## 圖形拉正 ```javascript= import cv2 import numpy as np img = cv2.imread("img2.jpg") width, height = 350,250 pts1 = np.float32 ([[978, 404],[1450, 210],[1025, 593],[1530, 480]]) pts2 = np.float32 ([[0, 0],[width, 0],[0, height], [width, height]]) matrix = cv2.getPerspectiveTransform(pts1, pts2)//這個需要用浮點數 imgOutput = cv2.warpPerspective(img, matrix, (width,height)) for x in range (0,4): cv2.circle(img, (int(pts1[x][0]), int(pts1[x][1])), 5 ,(0 , 0 , 255), cv2.FILLED) cv2.imshow("img", img) cv2.imshow("imgOutput", imgOutput) cv2.waitKey(0) ``` ![](https://i.imgur.com/7s8mWuX.png) ## 鼠標打點 ```javascript= import cv2 #import numpy as np img = cv2.imread('img2.jpg') cv2.imshow("img", img) def mousePoints(event,x,y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print(x,y) cv2.setMouseCallback("img", mousePoints) cv2.waitKey(0) ``` click img 上的任一點即會出現該點的XY座標 ![](https://i.imgur.com/M1s1HO0.png) ## 鼠標打點+圖形拉正 ```javascript= import cv2 import numpy as np def mousePoints(event,x,y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print(x,y) img = cv2.imread("img2.jpg") width, height = 350,250 pts1 = np.float32 ([[978, 404],[1450, 210],[1025, 593],[1530, 480]]) pts2 = np.float32 ([[0, 0],[width, 0],[0, height], [width, height]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) imgOutput = cv2.warpPerspective(img, matrix, (width,height)) cv2.imshow("imgOutput", imgOutput) for x in range (0,4): cv2.circle(img, (int(pts1[x][0]), int(pts1[x][1])), 5 ,(0 , 0 , 255), cv2.FILLED) cv2.imshow("img", img) cv2.setMouseCallback("img", mousePoints) cv2.waitKey(0) ``` ![](https://i.imgur.com/8YumXNI.jpg) ## 儲存鼠標,click XY 接下來要儲存點的(XY) ```javascript= import cv2 import numpy as np circles = np.zeros((4,2),np.float)//設置陣列4*2 counter = 0 def mousePoints(event,x,y, flags, param): global counter if event == cv2.EVENT_LBUTTONDOWN: circles[counter] = x,y counter = counter + 1 print(circles) img = cv2.imread("img2.jpg") cv2.imshow("img", img) cv2.setMouseCallback("img", mousePoints) cv2.waitKey(0) 6.png ![Uploading file..._5z0plwqs1]() ![Uploading file..._smgkrgk71]() ``` ## 建立LOOP 因為陣列只能存取四次資料(Click point) 接下來需要建立 while迴圈給他跑 ```javascript= import cv2 import numpy as np circles = np.zeros((4,2),np.float) counter = 0 def mousePoints(event,x,y, flags, param): global counter if event == cv2.EVENT_LBUTTONDOWN: circles[counter] = x,y counter = counter + 1 print(circles) img = cv2.imread("img2.jpg") while True: if counter == 4: width, height = 350,250 pts1 = np.float32 ([[circles[0]],[circles[1]],[circles[2]],[circles[3]]]) pts2 = np.float32 ([[0, 0],[width, 0],[0, height], [width, height]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) imgOutput = cv2.warpPerspective(img, matrix, (width,height)) cv2.imshow("imgOutput", imgOutput) cv2.imshow("img", img) for x in range(0, 4): cv2.circle(img, (int(circles[x][0]), int(circles[x][1])), 3, (0, 0, 255), cv2.FILLED) cv2.imshow("img", img) cv2.setMouseCallback("img", mousePoints) cv2.waitKey(1) ``` ![](https://i.imgur.com/hK5Cm3v.png) :::spoiler 一篇一個OpenCV函式(cvtColor) cv2.cvtColor(src, code, dst=None, dstCn=None) - 參數解釋: src:輸入圖像即要進行顏色空間變換的原圖像,可以是Mat類。 code:轉換的代碼或標識,即在此確定將什麼制式的圖片轉換成什麼制式的圖片。 dst:它是與src圖像大小和深度相同的輸出圖像。它是一個可選參數。 dstCn:它是目標圖像中的頻道數。如果參數為0,則通道數自動從src和code決定。它是一個可選參數。 函數的作用是將一個圖像從一個顏色空間轉換到另一個顏色空間 但是從RGB向其他類型轉換時,必須明確指出圖像的顏色通道 前面我們也提到過,在opencv中,其默認的顏色制式排列是BGR而非RGB。 所以對於24位顏色圖像來說, 前8-bit是藍色,中間8-bit是綠色,最後8-bit是紅色。常見的R,G,B通道的取值範圍為: . 0-255 :CV_8U類型圖片 . 0-65535: CV_16U類型圖片 . 0-1: CV_32F類型圖片 對於線性變換來說,這些取值範圍是無關緊要的。 但是對於非線性轉換,輸入的RGB圖像必須歸一化到其對應的取值範圍來或得最終正確的轉換結果, 例如從RGB->L*u*v轉換。 如果從一個8-bit類型圖像不經過任何縮放(scaling)直接轉換為32-bit浮點型圖像 函數將會以0-255的取值範圍來取代0-1的取值範圍 所以在使用cvtColor函數之前需要對圖像進行縮放如下: ```javascript= img *=1./255 cvtColor(img, img, CV_BGR2Luv) ``` 這裡列出的類型並不齊全,但是對於一般的圖像處理已經夠用。 需要特別說明的是RGB–>GRAY的轉換是我們常用的轉換格式,其轉換公式如下: RGB[A] to Gray: Y=0.299*R+0.587*G+0.114B 上圖中出現的RGBA格式圖片,RGBA是代表Red(紅色)、Green(綠色)、Blue(藍色)和Alpha的色彩空間 雖然它有時候被描述為一個顏色空間,但是它其實是RGB模型附加了額外的資訊,可以屬於任何一種RGB顏色空間 Alpha引數一般用作不透明度引數,如果一個畫素的alpha通道數值為0% 那它就是完全透明的也就是肉眼不可見,而數值為100%則意味著一個完全不透明的畫素 傳統的數字影象就是alpha值為100% 需要注意的是cvtColor()函式不能直接將RGB影象轉換為二值影象(Binary Image) 需要藉助threshold()函式,其具體用法請查閱threshold(). ```javascript= # 使用opencv讀取影象,直接返回numpy.ndarray 物件,通道順序為BGR ,注意是BGR,通道值預設範圍0-255。 img = cv.imread(r".\1.png") # 相對路徑 cv.imshow("IMAGE_BGR",img) # 在Image視窗中顯示圖片img img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 將彩色影象轉換為灰度影象 img_hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) # 將彩色影象轉換為HSV影象 cv.imshow("IMAGE_GRAY",img_gray) cv.imshow("IMAGE_HSV", img_hsv) ``` https://blog.csdn.net/keith_bb/article/details/53470170 ::: :::spoiler 一篇一個numpy函式() ```javascript= // ``` https://hackmd.io/@yillkid/rJp5h90s8/https%3A%2F%2Fhackmd.io%2F%40yillkid%2FHy5a_5A-F#array ::: ###