2011-12-18 66 views
0

我在並行區域使用Mat::convertTo(),它不會將矩陣數據轉換爲特定類型。但我測試過其他功能,例如cv::threshold()cv::imshow()。它工作正常。我不知道什麼是錯的。請參閱我的代碼如下:Mat :: convertTo不支持OpenMP

// Mat dst is CV_32FC1 
    if(dst.type() != CV_8UC1) 
    { 
     int rows = dst.rows; 
     #pragma omp parallel num_threads(2) 
     { 
      int numt = omp_get_num_threads(); 
      int tid = omp_get_thread_num(); 
      int start = tid*(rows/numt); 
      int end = (tid+1)*(rows/numt); 
      if(tid == (numt-1)) 
      { 
       end = rows; 
      } 

      Mat tmp = dst.rowRange(start, end); 
      tmp.convertTo(tmp, CV_8UC1); 
    } 

並行區域被執行,但dst的類型仍然是CV_32FC1。我的代碼中有什麼問題?任何幫助將不勝感激。

方面, 楠

+1

這是行不通的,因爲你不會在任何地方改變'dst'的類型。代碼中還缺少一個大括號。 – 2011-12-18 16:47:04

+0

謝謝@macs,但我仍然不清楚你的建議。你能指導我一段代碼什麼的嗎?由於'Mat :: rowRange()'爲'dst'的行跨度創建了新的標題。所以如果我轉換'tmp'類型,爲什麼'dst'類型仍舊是舊類型。對不起這個無稽之談的問題。我是opencv的新手。 :) – 2011-12-19 02:55:07

+0

這是因爲你正在創建'dst.rowRange'的副本。所以,當改變'tmp'的類型時,你並沒有改變'dst'的類型。如果你提供更多的代碼,這也會很有幫助。現在這個算法對我來說並沒有什麼意義。 – 2011-12-19 05:19:10

回答

0

幾乎所有墊的檢查工作目標墊的尺寸和類型的功能。如果他們是相同的,他們使用它們。所以,如果你的閾值與

threshold(src, src, ...); 

將處理就地

但是墊子上,如果目標墊子大小不同,類型,通道數等,它會ALLOC一個新的。在您的例子:

tmp.convertTo(tmp, CV_OTHER_TYPE); 

你現在假設DST,這實際上是TPM的來源,將改爲:

dst(tmp_region_ofInterest).convertTo(dst(region)); 

但實際上擴展到

Mat tmp2(tmp.size, CV_OTHER_SIZE); 
tmp.convertTo(tmp2,...); 
tmp = tmp2; 

而且在函數退出後,你的tmp不再是dst的一個區域。

原因很簡單:首先,您不能在原地更改類型,也不能更改部分矩陣的類型。你想要發生什麼?有矩陣(內存中的連續空間),充滿了unsigned charfloat的混合?因爲這會發生,至少在某些時候處理。

因此,如果一個給定的功能在適當的位置運行,並且它在感興趣的區域運行,並且它可以在感興趣的區域運行,那麼請始終檢查文檔。並且用常識填補官方文檔中缺失的空白。