2015-04-29 272 views
2

我已經編寫了一個實時檢測正方形(白色)並在其周圍繪製框架的代碼。正方形的長度l的每一邊被分成7部分。然後在垂直於三角形邊緣的偏差(藍色)演變出來的六個點中的每一點繪製一條長度爲h = l/7的線。角落標記爲紅色。然後,它看起來是這樣的:從顏色創建遮罩在C++中創建遮罩(疊加彩色圖像遮罩)

enter image description here

對於藍線和圓圈我有一個3通道(CV_8UC3)矩陣drawing,它是一個零無處不在,除了在的位置的繪製的紅色,藍色和白線。然後,我通過opencv的addWeighted函數將這個矩陣放在我的攝像頭圖像上。 ()。 但是,正如你所看到的,我得到的效果是我的破折號和圓圈的顏色在黑色區域外面是錯誤的(可能在黑色區域內也不正確,但在那裏更好)。它完全理解它爲什麼會發生,因爲它只是增加了一個重量的矩陣。

我想讓矩陣drawing在我的圖像上顯示正確的顏色。問題是,我不知道如何解決它。我不知何故需要一個面具drawing_mask,我的破折號在那裏疊加在我的相機圖像上。在Matlab的東西dst=webcam_img; dst(drawing>0)=drawing(drawing>0);

任何一個想法如何在C++中做到這一點?

回答

2

1.定製版本

我會明確地寫:

const int cols = drawing.cols; 
const int rows = drawing.rows; 

for (int j = 0; j < rows; j++) { 
    const uint8_t* p_draw = drawing.ptr(j); //Take a pointer to j-th row of the image to be drawn 
    uint8_t* p_dest = webcam_img.ptr(j); //Take a pointer to j-th row of the destination image 
    for (int i = 0; i < cols; i++) { 
     //Check all three channels BGR 
     if(p_draw[0] | p_draw[1] | p_draw[2]) { //Using binary OR should ease the optimization work for the compiler 
      p_dest[0] = p_draw[0]; //If the pixel is not zero, 
      p_dest[1] = p_draw[1]; //copy it (overwrite) in the destination image 
      p_dest[2] = p_draw[2]; 
     } 
     p_dest += 3; //Move to the next pixel 
     p_draw += 3; 
    } 
} 

當然你也可以在參數(const cv::Mat& drawing, cv::Mat& webcam_img)功能移到此代碼。

2. OpenCV的「純粹」的版本

但純OpenCV的方法是如下:

cv::Mat mask; 
//Create a single channel image where each pixel != 0 if it is colored in your "drawing" image 
cv::cvtColor(drawing, mask, CV_BGR2GRAY); 
//Copy to destination image only pixels that are != 0 in the mask 
drawing.copyTo(webcam_img, mask); 

效率較低(顏色轉換,以創建蒙版是有點貴),但肯定更緊湊。小記:如果您有一種非常暗的顏色,例如(0,0,1),它將在灰度級中轉換爲0,但它不起作用。


另外請注意,這可能是重新繪製相同覆蓋(線條,圓)在您的目的地形象,基本上調用所做創建您drawing圖像相同的抽籤操作成本更低。

+1

完美的作品,非常感謝。我在一個函數中實現了第一個解決方案。這工作得很好。 然後我讀了最後一個註釋,只是將我的覆蓋圖重繪到'webcam_img'中。這可能是我說的最快最簡單的解決方案。太好了謝謝。 SemtexB – SemtexB