Re: [問題] 關於OpenCV鍵盤事件的疑問(waitKey())

看板C_and_CPP作者 (TDiCS)時間8年前 (2016/03/10 23:30), 8年前編輯推噓1(102)
留言3則, 2人參與, 最新討論串2/2 (看更多)
: 感激不盡,程式碼如下: : while(1){ : . : . : . : while (1){ //希望可以退出這個迴圈 : for (int q = 30; q < 149; q++) : { : cvShowImage("image", Image); : for (int w = 0; w < 4000; w+) : { : FillRectangle(XYZ_New[q][w][0], XYZ_New[q][w][1], XYZ_New[q][w][2]); : } : Delay_DoEvents(0.001); : } : key = waitKey(1); //有時候抓不到 : printf("%d\n", key); : if (key == '1') : { : Pointx = Pointx + 10; : break; : } : else if (key == '2') : { : Pointx = Pointx - 10; : break; : } : } : } : 推 suwako: 我自己簡單測試了一下 沒有抓不到的問題阿 03/10 07:52 : 改成waitKey(100)就可以了,可能是鍵盤的沒船那麼那麼快@@ : 感激不盡! : 有幾個要點,個人覺得你不是弄得很清楚 首先,使用 waitKey() 時候 你希望 flow 繼續跑,不要卡住 因此有人提議使用 waitKey(1) 你用了之後,發現會漏觸發 接著改用 waitKey(100) 發現好像不會漏了 不過依照經驗,其他使用者來使用的話,還是會有機會漏掉 原因是,code 是你寫的,所以你知道 畫完圖後,只有一小段時間來等待 key in 因此你可以做到百發百中 甚至你可以做到預判,因為你知道繪圖何時快結束 有點像紅燈倒數,預先起步的情況 先回到 waitKey(1) 抓不到的問題 經驗來說 keyDown 到 keyUp 大約是 100 ~ 300 ms 但 waitKey(1) 只等待了 1 ms 假設你沒有預判,而確實等繪圖完全結束後,你在按下按鍵 你覺得 你的反應時間能每次都命中那 1 ms 我是每次都會 miss 啦 假設你預判了 有效觸發的條件是,waitKey(1) 剛好落在這次 keyDown - KeyUp 之間 所以你預判加上你每次按下時間是否都會剛好符合條件? 綜合以上,你使用 waitKey(1) 就會時有時無 其實你可以試試看,改回 waitKey(1) 然後在繪圖快結束之前 做 keyDown 而不 KeyUp,你會發現百發百中 因為故意使 按下時間 會涵蓋到 waitKey(1) 而如果在 keyUp 後才跑到 waitKey(100) 那當然也不會觸發 但是為什麼會變成比較容易,甚至百百中呢? 原因是,綜合預判、按下時間、waitKey(100) 整個反應至少會拉到 100~250 ms 這個時間,對於已知的反應來說,很夠了 以上總歸為 時序、時機 如果希望效果是 或 類似並列運行,會常常遇到相關問題 --- 另外 : → bdvstg: 為什麼waitKey不寫在回圈內 印象中畫面需要waitKey來更新 03/10 10:4 因為 code 加了 Delay_DoEvents(0.001); 如果我猜測沒錯,該 Func 是對此 thread delay 1 ms or (0.001 ms) 並且釋放出資源給其他 event 先執行 ( 如果裡面有相關 code 的話 ) 因此畫面會更新,而不用等整個 for loop 都結束才一次刷新 : 寫在for面的話,如果圖更新到一半有按鍵它就會直接跳出重新繪圖 其實,如果只是把 waitKey(1) 放到 for loop 內 應該是不會畫到一半就跳出重繪啦 不過如果把 if(key == ???) 也放進去就會中途跳出了 而且 如過沒有保留原本 2nd while(1) 的 if(key==??) 是不會跳出 2nd while(1) 的 不過單純將 key = waitKey(1) 放到 for loop 內 需要做一些小修正,不然依舊會有問題 提示,waitKey 可能會跑多於一次,然後... 另外,waitKey(1) 可能會造成另一個問題的 此處的 1 意指 1 ms 但實際上真的是 1 ms 嗎? Delay_DoEvents(0.001) 真的是 0.001 嗎? 如果誤差不大,那可能不明顯甚至沒感覺繪圖不流暢 但真的其他 event 占用比較多的時間 就會造成明顯繪圖不連貫的問題 : 我是希望可以整張圖繪完,有按鍵在重新繪圖 : 沒有按鍵就一直會原本的圖 我覺得,實際運行,跟你的回答是有誤差的喔 你說沒有按鍵,就一直是原本的圖 對於呈現出來的結果是沒錯的 但是對於整個流程來說,如果都沒有按下 '1' or '2' 那張圖是 一直在重繪 一直再重繪 一直再重繪 原本的結果 因為 waitKey(N>0) 是不會卡住的, 所以最終會回到 第二個 while(1) 起始,在跑一次 如果 XYZ_New[][][] 跟 Image 在沒有 key '1' or '2' 是不變的話,重繪其實有點占用資源 不過重繪也可以解決其他問題 例如,想要的效果就是某些 Image 之上是有動畫的 又例如有其他視窗 overlap 到你這個視窗上面 然後移開,可能會黑一塊,或者 Image 還在 方框不見一部分的情況 : 推 storm654321: waitKey 要拿來抓有沒有按按鍵不是嗎?@@不是一定要擺 03/10 16:4 : → storm654321: 嗎? 03/10 16:4 : 抱歉>< ,不是很懂你的意思? 我也不是很懂 要抓按鍵一定要用 waitKey 所以要擺 waitKey 嗎? 簡單來說 是沒錯,不過抓 key 的方法不只一種 還是 waitKey 一定要擺在 for loop 內? 端看你想把 waitKey 拿來幹啥用 單純 拿 key 做判斷的話,就不一定,例如原 PO 的用法 拿來 re 畫面,原 PO 也用了另一種方式 以上,動畫很好玩滴 個人追求會動就好 XD -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.231.111.96 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1457623816.A.7C1.html ※ 編輯: FancyWing (61.231.111.96), 03/10/2016 23:34:34

03/11 07:25, , 1F
如果要按下按鍵才更新圖 用waitKey(0)讓他一直等就好了阿
03/11 07:25, 1F

03/11 08:54, , 2F
因為他不要啊,有其他計算
03/11 08:54, 2F

03/11 10:32, , 3F
分一個thread出來waitKey 應該是最有效的辦法了
03/11 10:32, 3F
文章代碼(AID): #1MuPC8V1 (C_and_CPP)
文章代碼(AID): #1MuPC8V1 (C_and_CPP)