標籤:blog http io ar for strong 檔案 sp div
原文轉自:
http://blog.csdn.net/tutuguaiguai0427/article/details/6646051
這陣子,確切說這幾天,還是看了好多東西的。雖然無用功居多。
上篇日誌說的東西做完以後暫時就沒事了,然後窩實驗室吹著空調做我的小屋。
後來實在覺得無聊找了點事做。
第一天是打算消除視頻浮水印的。其實最土或者說其實最有效方法是單幀PS,但是,明顯我不是這麼勤快的人。我學的可不是PS,總覺得這是搞設計之類的人用的。
然後記得上次在xiaotie部落格看過程式除浮水印的,又翻出那篇文章,具體代碼沒有,只有思路。
雖然他說半透明的浮水印才可以去,不然修複不了。
但,為了消除那個徹底不透明的浮水印,我還是試了他的方法。
1.手動做mask圖片。想想一個視頻也就P一個圖還是能承受的,如果不是手動的話這個程式可就麻煩了,何況效果不一定好。我先把視頻用opencv播放,放一幀寫一張圖片,這樣可以挑一張純一點的圖片方便摳浮水印。
2.實驗單張圖片效果。隨便載入一張有那個浮水印的圖片,然後用PS的浮水印圖片做MASK,用inpaint函數。調了幾下半徑,效果也就一般,可以去掉浮水印但是那一塊地方總有雜色。如果視頻本來就不清晰,雜色比較多,或者需要重新打上你自己的浮水印(這個比較邪惡)那還行。MASK不同出來的效果也不同,我試過精確按文字形狀的和直接抹成一條的各種mask。有的出來是一團雜色,有的則是一小塊一小塊的。
3.其實我沒做3,第二步效果好的話其實第三步就是類似於批處理了,就是播放視頻,讀幀,處理,寫幀。然後就木有然後了。
需要注意的是用inpaint函數的時候,應該說用mask的時候,那個mask不是直接用PS塗成黑白就可以的。mask需要單通道8位的圖片,試了幾次失敗以後我就把圖片載入,然後在程式處理成8位單通道。處理完也可以存檔,然後以後直接讀那個圖作為MASK就可以了。處理的時候用threshold()函數處理一下,每個像素不是0就是1。用mask的時候就不處理0的點了。
然後那個就告一段落了,再做一個視頻捕捉,播放,,錄製功能的軟體,圖片還要增加文字和當前系統時間,介面用C#。
出於慣性思維直接開啟opencv,一小時之內絕對能搞定。然後C#寫介面,C++託管,搞定。然後悲劇的根源就是試圖將opencv跳出的框塞進C#,反正就那效果,懂得。
其實之前就有這個問題,C#+opengcv那個播放視頻的視窗固定不了,只能是從介面蹦出來的。但是當時逃避了一下,後來改用了WMP的控制項,因為那次只是播放本地的視頻,WMP還直接支援捲軸前進後退的,真爽。但這次是逃不過了。糾結於各種諸如bitmap、控制代碼之類的問題後,發現可以用設定父視窗的辦法。
[cpp] view plaincopy
- cvNamedWindow("Capture");
- // 將這個視窗縮至最小
- cvResizeWindow("Capture",1,1);
- // 擷取視窗控制代碼
- HWND hWnd = (HWND) cvGetWindowHandle("Capture");
- // 擷取該視窗的父視窗控制代碼
- HWND hParent = ::GetParent(hWnd);
- // 擷取C#form1視窗控制代碼
- HWND hwnd1=::FindWindowW(NULL,L"Form1");
- //HWND hwnd2=::FindWindowEx(hwnd1,NULL,NULL,L"pictureBox1");//這個居然就失敗,會定位到案頭的左上方HWND hwnd3=::FindWindowEx(hwnd1,NULL,NULL,NULL);
- if(!hwnd3)cvNamedWindow("C");//其實這句作用類似於message,我隨手寫的,神奇的是,不加這句的時候怎麼都不行,一加居然就好了,然後我也就沒改
- // 將GUI視窗設定為視頻播放視窗的父視窗,使視頻在 GUI 的指定地區播放
- ::SetParent(hWnd, hwnd3);
- // 隱藏所建立的視頻播放視窗 ::ShowWindow(hParent, SW_HIDE);
但是這樣還是會先跳出一個框,然後它就鑽進C#的介面了,估計電腦卡會很明顯。嗚嗚。
之前用opencv的時候都是用waitKey的辦法用鍵盤控制錄製、之類的功能。
但是按鍵的時候焦點肯定需要在opencv的視窗,於是又悲劇了。
花了很久都沒有搞定,不知道怎麼讓焦點選到那個跳出的視窗,此時已經是隱藏了的。
反正我到現在還不知道怎麼搞。在這荒涼到長草的部落格裡,我想應該也不會有幾個人看我日誌,然後就更沒什麼人會解答這個問題了吧。
想了很久,覺得其實就這樣幾個思路,一是想辦法把那個隱藏的設為焦點,二是傳遞事件,從C#傳到dll裡的C++,三是opencv寫的那部分只返回圖片,還是要bitmap的。
前兩個我都失敗了,第三個各種糾結以後發現如果不在opencv轉換的話也不行,C#和c++都只認識自己的圖片的類型,據說CLR也是可以支援C#那個,但是我的不行。
opencv轉換有一個函數,2.2版本剛好取消,有人把它摳出來,我添加以後提示缺少一個標頭檔,加入以後發現是MFC的,然後配置也要改,改完不支援原來的。總之,也失敗了。
求助師兄的時候他說那些按鍵的控制不能寫在opencv,必須從opencv返回圖片,至於轉換他是記憶體RGB流寫成bitmap。於是,我知道,我的路走不下去了。等轉換完這效率都不知道啥樣了。
網上搜的那些大部分都用的是emgu,在C#用託管用opencv的貌似不多。我也發現這樣調試不方便。
繼續掙紮了很久,未遂,決定用MFC,但是,又放棄了,重回C#。
這次選擇了emgu。果然很方便,不用託管,函數也現成。
滿懷希望的運行,發現網路攝影機顯示的畫面始終黑色,自己加的文字可以看到。
去emgu內建的例子運行,也是這個情況。
然後我就崩潰了,上次用emgu就是各種配置問題,當時opencv和emgu都換成64位就可以了,這次連64都不行啊。程式在別人32的機子上跑,emgu換成32位,工程也選擇32位,連一幀都沒取到。ORZ。
掙紮了很久我決定繼續放棄emgu,然後,目標轉向Aforge.NET。當時就聽說它很強大但是資料很少。山窮水盡的時候管它有沒有資料,反正相機擷取這種對視覺庫本來就感覺有點殺雞用牛刀的意思。從來沒接觸過這個,下載,安裝。發現最新版本是27號才發布的,裡面剛好添加了寫視頻檔案的新的類。NICE。
跟emgu一樣,開發效率也很高。這次吸取教訓先試試系統內建例子能否運行。事實證明很成功。
放心大膽的寫。也沒多久就OK了。運行。又崩潰。那個新添加的庫無法載入。"Could not load file or assembly ‘AForge.Video.FFMPEG.dll‘ or one of its dependencies. The specified module could not be found."想死的心都有了。
這個庫果然資料很少。找到官網的論壇,發現整個論壇AFoge.NET Framework部分只有為數不多的人發個文章問問題,然後基本只有管理員在回答。
管理員的location還是英國。不知道是哪國人,反正都是英語發帖。
發了個文章問完以後因為上一天寢室太熱一整晚沒睡著所以就趴著睡了覺。睡醒探索管理員回複了。讓我把Externals\ffmpeg\bin下的dll自己拷到工程的output檔案夾。照做以後
“Mixed mode assembly is built against version ‘v2.0.50727‘ of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.",繼續把錯誤資訊發到文章上。很快管理員就回複了。真好的人啊。給了我一個文章的連結,是google出來的結果,還很含蓄的告訴我要勤於google。汗。
第一種方法是修改app.exe.config
[html] view plaincopy
- <?xml version="1.0"?>
- <configuration>
- <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>
第二種是把4.0降下來。
因為沒有成功編譯,所以我沒有那個config檔案。(後來想想真傻,把那個庫注釋掉不就行了麼。)
所以只能降成.NET3.5。還自己編譯了2.0的dll。再編譯我的工程。結果那個之前出問題的dll居然依賴.NET4.0的檔案。ORZ。
於是我只能換回來4.0。這時候居然發現可以運行了說。但保險起見我還是把config給修改了。
再跑的時候發現錄製的時候我可以用USB的網路攝影機,筆記本的不能用。預覽都可以的。
再問管理員GG,人家又迅速回覆了,說這個庫不認你用的是啥裝置,應該是別的問題。
然後當我把fps設定去掉的時候,內建的可以用了,USB的罷工了。
之後就是嘗試各種fps,發現設定8的時候都可以用。
用系統內建的例子測了下網路攝影機的fps,USB的就8-9,內建的9-10的樣子,因為那個是動態測量的。
然後就只能設fps,試試會不會掛了。
還有之前說的加時間加文字。時間很好實現,C#有對應的函數。但opencv是不支援添加中文的字串的,emgu所以也不支援。用aforge.NET的時候就可以了。opencv下有人是安裝字型檔來實現的,看著好複雜。
至於很多人也有的一個問題,就是錄進去的視頻特別快。尤其我這樣添加了時間,走快了很明顯。
今天終於想通了。我太高估我網路攝影機了。AVI的幀率設的25,以前沒發現網路攝影機連它一半幀率都沒到,也就是一秒才捕10幀,我楞寫25幀到avi,當然就走的快了,再加壓縮的時候應該也是有損失的。但是當我把檔案設到很低的時候有時候有會出錯,跟先前設fps的時候一樣的錯誤,說視頻檔案無法開啟(其實就是建立)。
寫到這裡的時候我突然在想,如果還是fps25,忽略連貫的問題,只考慮準確走時,也許可以設一個定時器,固定時間寫入,不管有沒有新幀,反正某個變數裡面有新幀就替換,沒有就繼續寫原來的。一會試試,這個估計不太花時間。如果還是不行就先這樣吧。
因為現在有新任務了,做視頻摘要。
貝貝加油,哦耶。
【轉】終於幹了點正事。。三天用了三個庫opencv、emgu、aforge.net[2011.7.30]