1. 程式人生 > >javacv windows下視訊提取幀再轉化為灰度直方圖

javacv windows下視訊提取幀再轉化為灰度直方圖

opencv+javacv+eclipse+windows 從視訊到——灰度直方圖

最近在做storm的專案,由於storm不能很好的支援C++,所以決定用java來實現下從視訊到關鍵幀再到灰度直方圖的操作。於是接觸到opencv,查了相關資料和別人的一些帖子進一步瞭解到可以通過javacv在eclipse部署之後方可實現。

相關的javacv的不是操作,相關的資料也有不少,這裡不再具體講解安裝和部署的過程,只把中間注意的問題列一下:

1.因為opencv和javacv都需要jar包的引入,所以版本的選擇很重要,我選的是javacv1.0 +opencv2.4.9,其實開始下載的是比較新的版本opencv3.0,一直出現util的錯誤,後來就改為2.4.9了。

2.解壓安裝包時,儘量放在C盤的根目錄,否則有時候會編譯出錯,當然這一步不是必須的。

3.jar包的引入,一定要與系統的位數對應,例32位作業系統就使用x86的相關jar。

4.相關環境變數的配置,這裡不再複述,否則會出現java.library.path類似的錯誤。

 在部署好環境之後,可以先用一段程式碼進行測試:

public static void main(String[] args) {  
    //讀取影象  
    IplImage srcImg=cvLoadImage("data/SouthEast.jpg");//這裡改成自己的路徑 
    if (srcImg !=null) {  
        
        cvNamedWindow("test");  
   
        cvShowImage("test",srcImg);  
    
        cvWaitKey(0);  
  
        cvReleaseImage(srcImg);  
       
       cvDestroyWindow("test");   
    }  

測試成功後,可以進行視訊的提取幀操作了,這裡我是按照每3秒提取一幀(基本思路是先獲取輸入視訊流的幀率,每次跳過3秒所包含的幀率即可),程式碼如下:

CvCapture capture = opencv_highgui.cvCreateFileCapture("C:/Users/hp03/Desktop/www.ygdy8.com.rmvb");  
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>    //每秒幀率  
<span style="white-space:pre">	</span>    int fps = (int) opencv_highgui.cvGetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FPS);  
<span style="white-space:pre">	</span>    while (true) {       //讀取關鍵幀     <span style="white-space:pre">	</span>     
<span style="white-space:pre">	</span>        frame = opencv_highgui.cvQueryFrame(capture);  <span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>        //得到灰度值
<span style="white-space:pre">	</span>         getGray(frame.getBufferedImage());
<span style="white-space:pre">	</span>      int  count=fps*3;
<span style="white-space:pre">	</span>        while(count > 0 ){ //每3秒取一幀  
<span style="white-space:pre">	</span>            frame = opencv_highgui.cvQueryFrame(capture);  
<span style="white-space:pre">	</span>            count--;   
<span style="white-space:pre">	</span>        }          
<span style="white-space:pre">	</span>        if (null == frame)  
<span style="white-space:pre">	</span>            break;           
<span style="white-space:pre">	</span>    }  <span style="white-space:pre">	</span> 
為了得到灰度值但javacv的文件又太少,則看了下opencv的原始碼,自己實現下gray值的提取,其實很簡單:
for (int i = 0; i < image.getWidth(); i++) {
  			for (int j = 0; j < image.getHeight(); j++) {
  				final int color = image.getRGB(i, j);
  				final int r = (color >> 16) & 0xff;
  				final int g = (color >> 8) & 0xff;
  				final int b = color & 0xff;
  				int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);;
要把圖片灰度值統計成直方圖,也就是放到陣列統計即可,以上就是整個思路講解。

最後,附上整體的程式碼如下:

public class Test{
	 public static void main(String[] args) {  
	     //   System.out.println(System.getProperty("java.library.path"));  
	        Real t = new Real();  
	        t.run();  
	    }  
	public void run() { //視訊轉化為幀、秒 
		CvCapture capture = opencv_highgui.cvCreateFileCapture("C:/Users/hp03/Desktop/www.ygdy8.com.rmvb");  
		System.out.println("讀取視訊成功!!!!!");  
	    //每秒幀率  
	    int fps = (int) opencv_highgui.cvGetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FPS);  
	    System.out.println("幀率:"+fps+"沒三秒取一幀");   
	    IplImage frame = null;  	      
	    int count = 0;  
	    while (true) {       //讀取關鍵幀     	     
	        frame = opencv_highgui.cvQueryFrame(capture);  	
	        //得到灰度值
	         getGray(frame.getBufferedImage());
	        count=fps*3;
	        while(count > 0 ){ //每3秒取一幀  
	            frame = opencv_highgui.cvQueryFrame(capture);  
	            count--;   
	        }          
	        if (null == frame)  
	            break;           
	    }  	 
	    
	}  
	
	public void getGray(BufferedImage image){
		int[] Hist = new int[256];
		  for (int i = 0; i < image.getWidth(); i++) {
  			for (int j = 0; j < image.getHeight(); j++) {
  				final int color = image.getRGB(i, j);
  				final int r = (color >> 16) & 0xff;
  				final int g = (color >> 8) & 0xff;
  				final int b = color & 0xff;
  				int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);;
  				//System.out.println(i + " : " + j + " " + gray);
  			//	histogram(Hist,gray);	
  				Hist[gray]++;
  			}
  			
          }
		  System.out.print("[");
		  for (int i = 0; i < Hist.length; i++) {
			  System.out.print(Hist[i]+" ");
		}
		  System.out.println("]");
		  System.out.println("");
		  
	}