1. 程式人生 > >OpenCV講堂 滑鼠畫筆 setMouseCallback()

OpenCV講堂 滑鼠畫筆 setMouseCallback()

													<span class="tags-box artic-tag-box">
							<span class="label">https://blog.csdn.net/qton_csdn/article/details/70193884</span>
															<a data-track-click="{&quot;mod&quot;:&quot;popu_626&quot;,&quot;con&quot;:&quot;python&quot;}" class="tag-link" href="http://so.csdn.net/so/search/s.do?q=python&amp;t=blog" target="_blank">python																</a><a data-track-click="{&quot;mod&quot;:&quot;popu_626&quot;,&quot;con&quot;:&quot;opencv&quot;}" class="tag-link" href="http://so.csdn.net/so/search/s.do?q=opencv&amp;t=blog" target="_blank">opencv																</a><a data-track-click="{&quot;mod&quot;:&quot;popu_626&quot;,&quot;con&quot;:&quot;影象處理&quot;}" class="tag-link" href="http://so.csdn.net/so/search/s.do?q=影象處理&amp;t=blog" target="_blank">影象處理																</a><a data-track-click="{&quot;mod&quot;:&quot;popu_626&quot;,&quot;con&quot;:&quot;影象識別&quot;}" class="tag-link" href="http://so.csdn.net/so/search/s.do?q=影象識別&amp;t=blog" target="_blank">影象識別																</a><a data-track-click="{&quot;mod&quot;:&quot;popu_626&quot;,&quot;con&quot;:&quot;計算機視覺&quot;}" class="tag-link" href="http://so.csdn.net/so/search/s.do?q=計算機視覺&amp;t=blog" target="_blank">計算機視覺																</a>
						<span class="article_info_click">更多</span></span>
																				<div class="tags-box space">
							<span class="label">個人分類:</span>
															<a class="tag-link" href="https://blog.csdn.net/Qton_CSDN/article/category/6864130" target="_blank">計算機視覺																</a>
						</div>
																							</div>
			<div class="operating">
													</div>
		</div>
	</div>
</div>
<article class="baidu_pl">
	<div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post">
							<div class="article-copyright">
              					
				版權宣告:本文為博主原創文章,未經博主允許不得轉載。					https://blog.csdn.net/Qton_CSDN/article/details/70193884				</div>
							            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-d7e2a68c7c.css">
					<div class="htmledit_views" id="content_views">

目標

https://blog.csdn.net/qton_csdn/article/details/70193884

• 學習使用 OpenCV 處理滑鼠事件

• 你將要學習的函式是:cv2.setMouseCallback()


滑鼠事件 :cv2.setMouseCallback()

cv2_EVENT_MOUSEMOVE 0 滑動 
cv2_EVENT_LBUTTONDOWN 1 左鍵點選 
cv2_EVENT_RBUTTONDOWN 2 右鍵點選 
cv2_EVENT_MBUTTONDOWN 3
中間點選 
cv2_EVENT_LBUTTONUP 4 左鍵釋放 
cv2_EVENT_RBUTTONUP 5 右鍵釋放 
cv2_EVENT_MBUTTONUP 6 中間釋放 
cv2_EVENT_LBUTTONDBLCLK 7 左鍵雙擊 
cv2_EVENT_RBUTTONDBLCLK 8 右鍵雙擊 
cv2_EVENT_MBUTTONDBLCLK 9 中間釋放

cv2_EVENT_FLAG_LBUTTON 1 左鍵拖拽  
cv2_EVENT_FLAG_RBUTTON 2 右鍵拖拽  
cv2_EVENT_FLAG_MBUTTON
4 中間拖拽  
cv2_EVENT_FLAG_CTRLKEY 8 (8~15)按Ctrl不放事件  
cv2_EVENT_FLAG_SHIFTKEY 16  (16~31)按Shift不放事件  
cv2_EVENT_FLAG_ALTKEY 32  (32~39)按Alt不放事件(後面8-39還有待研究)

例項1 :雙擊左鍵畫圓圈 

用到的EVENT為:cv2_EVENT_LBUTTONDBLCLK

所有的滑鼠事件回撥函式都有一個統一的格式,他們所不同的地方僅僅是
被呼叫後的功能。我們的滑鼠事件回撥函式只用做一件事:在雙擊過的地方繪
制一個圓圈。下面是程式碼,不懂的地方可以看看註釋。


  
  1. import cv2
  2. import numpy as np
  3. import time
  4. img=cv2.imread( 'PIC/000.jpg') #讀取圖片作為背景
  5. #定義畫圓事件,如果事件雙擊左鍵發生
  6. #則以此時雙擊的點為原點畫一個半徑為100px BGR為(255,255,0)粗細為3px的圓圈
  7. def draw_circle(event,x,y,flags,param):
  8. if event==cv2.EVENT_LBUTTONDBLCLK:
  9. cv2.circle(img,(x,y), 100,( 255, 255, 0), 3)
  10. # 建立影象與視窗並將視窗與回撥函式繫結
  11. cv2.namedWindow( 'image')
  12. cv2.setMouseCallback( 'image',draw_circle)
  13. while( 1):
  14. cv2.imshow( 'image',img)
  15. if cv2.waitKey( 100) == ord( 'q'): #等待100毫秒 重新整理一次顯示影象
  16. break
  17. cv2.destroyAllWindows()


執行結果:



例項2

現在我們來建立一個更好的程式。這次我們的程式要完成的任務是根據我
們選擇的模式在拖動滑鼠時繪製矩形或者是圓圈(就像畫圖程式中一樣)。所以
我們的回撥函式包含兩部分,一部分畫矩形,一部分畫圓圈。這是一個典型的
例子他可以幫助我們更好理解與構建人機互動式程式,比如物體跟蹤,影象分
割等。
下面我們要把這個回撥函式與 OpenCV 視窗繫結在一起。在主迴圈中我
們需要將鍵盤上的“m”鍵與模式轉換繫結在一起。


  
  1. import cv2
  2. import numpy as np
  3. import time
  4. img=cv2.imread( 'PIC/000.jpg')
  5. # 當滑鼠按下時變為True
  6. drawing= False
  7. # 如果mode 為true 繪製矩形。按下'm' 變成繪製曲線。
  8. mode= True
  9. ix,iy= -1, -1
  10. # 建立回撥函式
  11. def draw_circle(event,x,y,flags,param):
  12. global ix,iy,drawing,mode
  13. # 當按下左鍵是返回起始位置座標
  14. if event==cv2.EVENT_LBUTTONDOWN:
  15. drawing= True
  16. ix,iy=x,y
  17. # 當滑鼠左鍵按下並移動是繪製圖形。event 可以檢視移動,flag 檢視是否按下
  18. elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
  19. if drawing== True:
  20. if mode== True:
  21. cv2.rectangle(img,(ix,iy),(x,y),( 0, 255, 0), -1)
  22. else:
  23. # 繪製圓圈,小圓點連在一起就成了線
  24. cv2.circle(img,(x,y), 3,( 0, 0, 255), -1)
  25. # 當滑鼠鬆開停止繪畫。
  26. elif event==cv2.EVENT_LBUTTONUP:
  27. drawing== False
  28. cv2.namedWindow( 'image')
  29. cv2.setMouseCallback( 'image',draw_circle)
  30. while( 1):
  31. cv2.imshow( 'image',img)
  32. k=cv2.waitKey( 1)& 0xFF
  33. if k==ord( 'm'):
  34. mode= not mode
  35. elif k==ord( 'q'):
  36. break


執行結果:




全部程式碼:


  
  1. '''函式:cv2.setMouseCallback()'''
  2. import cv2
  3. import numpy as np
  4. import time
  5. img=cv2.imread( 'PIC/000.jpg')
  6. def draw_circle(event,x,y,flags,param):
  7. if event==cv2.EVENT_LBUTTONDBLCLK:
  8. cv2.circle(img,(x,y), 100,( 255, 255, 0), 3)
  9. cv2.namedWindow( 'image')
  10. cv2.setMouseCallback( 'image',draw_circle)
  11. while( 1):
  12. cv2.imshow( 'image',img)
  13. if cv2.waitKey( 100) == ord( 'q'): #等待100毫秒 重新整理一次顯示影象
  14. break
  15. cv2.destroyAllWindows()
  16. # 當滑鼠按下時變為True
  17. drawing= False
  18. # 如果mode 為true 繪製矩形。按下'm' 變成繪製曲線。
  19. mode= True
  20. ix,iy= -1, -1
  21. 6
  22. # 建立回撥函式
  23. def draw_circle(event,x,y,flags,param):
  24. global ix,iy,drawing,mode
  25. # 當按下左鍵是返回起始位置座標
  26. if event==cv2.EVENT_LBUTTONDOWN:
  27. drawing= True
  28. ix,iy=x,y
  29. # 當滑鼠左鍵按下並移動是繪製圖形。event 可以檢視移動,flag 檢視是否按下
  30. elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
  31. if drawing== True:
  32. if mode== True:
  33. cv2.rectangle(img,(ix,iy),(x,y),( 0, 255, 0), -1)
  34. else:
  35. # 繪製圓圈,小圓點連在一起就成了線
  36. cv2.circle(img,(x,y), 3,( 0, 0, 255), -1)
  37. # 當滑鼠鬆開停止繪畫。
  38. elif event==cv2.EVENT_LBUTTONUP:
  39. drawing== False
  40. img=cv2.imread( 'PIC/000.jpg')
  41. cv2.namedWindow( 'image')
  42. cv2.setMouseCallback( 'image',draw_circle)
  43. while( 1):
  44. cv2.imshow( 'image',img)
  45. k=cv2.waitKey( 1)& 0xFF
  46. if k==ord( 'm'):
  47. mode= not mode
  48. elif k==ord( 'q'):
  49. break











				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>