基礎版筆記傳送門: python3+opencv學習筆記匯總目錄(適合基礎入門學習) 進階版筆記目錄: python+opencv進階版學習筆記目錄(適合有一定基礎)
感興趣區域傳統繪制: opencv學習筆記5:感興趣區域ROI
opencv 鼠標事件
1.opencv 鼠標事件類型
import cv2d
= [ i
for i
in dir ( cv2
) if 'EVENT' in i
]
print ( d
)
'EVENT_FLAG_ALTKEY' :代表拖拽事件。按住alt鍵不放
'EVENT_FLAG_CTRLKEY' 按住ctrl鍵不放
'EVENT_FLAG_LBUTTON' 按住左鍵拖拽
'EVENT_FLAG_MBUTTON' 中鍵拖拽
'EVENT_FLAG_RBUTTON' 右鍵拖拽
'EVENT_FLAG_SHIFTKEY' 按住shift不放
'EVENT_LBUTTONDBLCLK' event鼠標事件。左鍵雙擊
'EVENT_LBUTTONDOWN' 按下左鍵
'EVENT_LBUTTONUP' 釋放左鍵
'EVENT_MBUTTONDBLCLK' 中鍵雙擊
'EVENT_MBUTTONDOWN' 中鍵點擊
'EVENT_MBUTTONUP' 中鍵放開
'EVENT_MOUSEHWHEEL' 'EVENT_MOUSEMOVE' 滑動
'EVENT_MOUSEWHEEL' , 'EVENT_RBUTTONDBLCLK' , 右鍵雙擊
'EVENT_RBUTTONDOWN' , 右鍵點擊
'EVENT_RBUTTONUP' 右鍵釋放
2.opencv回調函數
cv2.setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)winname:窗口的名字
onMouse:鼠標響應函數,回調函數。指定窗口里每次鼠標時間發生的時候,被調用的函數指針。 這個函數的原型應該為void on_Mouse(int event, int x, int y, int flags, void* param);
userdate:傳給回調函數的參數
響應函數
void on_Mouse(int event, int x, int y, int flags, void* param);
event是 CV_EVENT_*變量之一
x和y是鼠標指針在圖像坐標系的坐標(不是窗口坐標系)
flags是CV_EVENT_FLAG的組合, param是用戶定義的傳遞到setMouseCallback函數調用的參數。
opencv 繪圖函數
1繪制直線 cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5) 參數:圖像名,起點,終點,顏色,筆寬/px
import numpy
as np
import cv2
img
= np
. zeros
( ( 512 , 512 , 3 ) , np
. uint8
)
cv2
. line
( img
, ( 0 , 0 ) , ( 511 , 511 ) , ( 255 , 0 , 0 ) , 5 )
cv2
. imshow
( 'image' , img
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
2繪制矩形 cv2.rectangle(img,(104,50),(300,128),(0,255,0),5) 參數:圖像名,左上角,右下角,顏色,筆粗細
import numpy
as np
import cv2
img
= np
. zeros
( ( 400 , 400 , 3 ) , np
. uint8
)
cv2
. rectangle
( img
, ( 104 , 50 ) , ( 300 , 128 ) , ( 0 , 255 , 0 ) , 5 )
cv2
. imshow
( 'image' , img
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
3繪制圓形 cv2.circle(img,中心點(x,y), 半徑, 顏色(0,255,255), -1或1) 參數:圖像名,中心點,半徑,顏色。-1是繪制真個圓,1邊框。
import numpy
as np
import cv2
img
= np
. zeros
( ( 400 , 400 , 3 ) , np
. uint8
)
cv2
. circle
( img
, ( 100 , 63 ) , 63 , ( 0 , 255 , 255 ) , - 1 )
cv2
. circle
( img
, ( 300 , 63 ) , 63 , ( 0 , 0 , 255 ) , 1 )
cv2
. imshow
( 'image' , img
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
4繪制橢圓
cv2.ellipse(img,(256,256),(100,50),0,0,120,(0,0,255),-1) 參數: 中心點坐標:如(256,256) 長軸和短軸長度:如(100,50) 夾角橢圓在逆時針方向旋轉的角度:如0 起始角和端角表示從主軸順時針方向測量的橢圓弧的開始和結束:如 0,120 顏色:如(0,0,255) 整個還是輪廓:-1表示整個橢圓,1表示輪廓
import numpy
as np
import cv2
img
= np
. zeros
( ( 400 , 400 , 3 ) , np
. uint8
)
cv2
. ellipse
( img
, ( 256 , 256 ) , ( 100 , 50 ) , 0 , 0 , 120 , ( 0 , 0 , 255 ) , - 1 )
cv2
. ellipse
( img
, ( 120 , 120 ) , ( 100 , 50 ) , 0 , 0 , 360 , ( 0 , 255 , 255 ) , 1 )
cv2
. imshow
( 'image' , img
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
5繪制多邊形 pts = np.array([[50,30],[150,30],[200,80],[40,90]], np.int32) 傳入的是幾個點的坐標,可以有很多點。
import numpy
as np
import cv2
img
= np
. zeros
( ( 400 , 400 , 3 ) , np
. uint8
)
pts
= np
. array
( [ [ 50 , 30 ] , [ 150 , 30 ] , [ 200 , 80 ] , [ 40 , 90 ] ] , np
. int32
)
pts
= pts
. reshape
( ( - 1 , 1 , 2 ) )
cv2
. polylines
( img
, [ pts
] , True , ( 0 , 0 , 255 ) )
cv2
. imshow
( 'image' , img
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
使用鼠標在圖片上繪制矩形框
繪制一個矩形框 方法1 這段代碼有借鑒其他博客
import cv2
global img
global point1
, point2
def Rectangular_box ( event
, x
, y
, flags
, param
) : global img
, point1
, point2img2
= img
. copy
( ) if event
== cv2
. EVENT_LBUTTONDOWN
: point1
= ( x
, y
) cv2
. circle
( img2
, point1
, 10 , ( 0 , 255 , 0 ) , 5 ) cv2
. imshow
( 'img' , img2
) elif event
== cv2
. EVENT_MOUSEMOVE
and ( flags
& cv2
. EVENT_FLAG_LBUTTON
) : cv2
. rectangle
( img2
, point1
, ( x
, y
) , ( 255 , 0 , 0 ) , 5 ) cv2
. imshow
( 'img' , img2
) elif event
== cv2
. EVENT_LBUTTONUP
: point2
= ( x
, y
) cv2
. rectangle
( img2
, point1
, point2
, ( 0 , 255 , 255 ) , 4 ) cv2
. imshow
( 'img' , img2
) min_x
= min ( point1
[ 0 ] , point2
[ 0 ] ) min_y
= min ( point1
[ 1 ] , point2
[ 1 ] ) width
= abs ( point1
[ 0 ] - point2
[ 0 ] ) height
= abs ( point1
[ 1 ] - point2
[ 1 ] ) cut_img
= img
[ min_y
: min_y
+ height
, min_x
: min_x
+ width
] cv2
. imshow
( 'result' , cut_img
def main ( ) : global imgimg
= cv2
. imread
( 'yangmi.jpg' ) img
= cv2
. resize
( img
, None , fx
= 0.4 , fy
= 0.4 ) cv2
. namedWindow
( 'image' ) cv2
. setMouseCallback
( 'image' , Rectangular_box
) cv2
. imshow
( 'image' , img
) cv2
. waitKey
( 0 )
if __name__
== '__main__' : main
( )
繪制一個矩形框 方法2 使用函數cv2.selectROI(windowName, img, showCrosshair=None, fromCenter=None) windowName:選擇的區域被顯示在的窗口的名字 img:要在什么圖片上選擇ROI showCrosshair:是否在矩形框里畫十字線. fromCenter:是否是從矩形框的中心開始畫
import cv2
img
= cv2
. imread
( 'fangye.jpg' ) r
= cv2
. selectROI
( 'ROI' , img
, False , False )
print ( r
)
imCrop
= img
[ int ( r
[ 1 ] ) : int ( r
[ 1 ] + r
[ 3 ] ) , int ( r
[ 0 ] ) : int ( r
[ 0 ] + r
[ 2 ] ) ]
cv2
. imshow
( "cut_image" , imCrop
)
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
結果r=(109, 44, 243, 153)
框選后 一點要點擊 Enter 鍵才顯示框選圖像。
繪制多邊形框 cv2.polylines:繪制多邊形框 cv2.fillPoly:填充多邊形框。把框內填滿,使其是多邊形。 這下面這段代碼借鑒博客 OpenCV-Python選擇ROI(矩形和多邊形)
import cv2
import numpy
as nppts
= [ ]
def on_mouse ( event
, x
, y
, flags
, param
) : img2
= img
. copy
( ) if event
== cv2
. EVENT_LBUTTONDOWN
: pts
. append
( ( x
, y
) ) if event
== cv2
. EVENT_RBUTTONDOWN
: pts
. pop
( ) if event
== cv2
. EVENT_RBUTTONDBLCLK
: mask
= np
. zeros
( img
. shape
, np
. uint8
) points
= np
. array
( pts
, np
. int32
) points
= points
. reshape
( ( - 1 , 1 , 2 ) ) mask
= cv2
. polylines
( mask
, [ points
] , True , ( 255 , 255 , 255 ) , 2 ) mask2
= cv2
. fillPoly
( mask
. copy
( ) , [ points
] , ( 255 , 255 , 255 ) ) mask3
= cv2
. fillPoly
( mask
. copy
( ) , [ points
] , ( 0 , 255 , 0 ) ) show_image
= cv2
. addWeighted
( src1
= img
, alpha
= 0.8 , src2
= mask3
, beta
= 0.2 , gamma
= 0 ) cv2
. imshow
( "show_img" , show_image
) ROI
= cv2
. bitwise_and
( mask2
, img
) cv2
. imshow
( "ROI" , ROI
) cv2
. waitKey
( 0 ) if len ( pts
) > 0 : cv2
. circle
( img2
, pts
[ - 1 ] , 3 , ( 0 , 0 , 255 ) , - 1 ) if len ( pts
) > 1 : for i
in range ( len ( pts
) - 1 ) : cv2
. circle
( img2
, pts
[ i
] , 5 , ( 0 , 0 , 255 ) , - 1 ) cv2
. line
( img
= img2
, pt1
= pts
[ i
] , pt2
= pts
[ i
+ 1 ] , color
= ( 255 , 0 , 0 ) , thickness
= 2 ) cv2
. imshow
( 'image' , img2
)
img
= cv2
. imread
( "fangye.jpg" )
cv2
. namedWindow
( 'image' )
cv2
. setMouseCallback
( 'image' , on_mouse
)
print ( "[INFO] 單擊左鍵:選擇點,單擊右鍵:刪除上一次選擇的點,雙擊右鍵:確定ROI區域" )
print ( "[INFO] 按 ESC 退出" )
cv2
. waitKey
( 0 )
cv2
. destroyAllWindows
( )
用下 范爺的美圖吧。來源于網絡。 這方法速度太慢。
電氣專業的計算機萌新。寫博文不容易。如果你覺得本文不錯,請點個贊支持下,謝謝。
總結
以上是生活随笔 為你收集整理的opencv进阶学习笔记6:使用鼠标在图像上绘制矩形框或者多边形框 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。