2017-02-27 26 views
2

當我試圖畫一個箭頭與OpenCV的3.2丟失:像素的箭頭提示使用抗鋸齒

#include <opencv2/core.hpp> 
#include <opencv2/imgproc.hpp> 
#include <opencv2/highgui.hpp> 

using namespace cv; 

int main() 
{ 
    Mat image(480, 640, CV_8UC3, Scalar(255, 255, 255)); //White background 
    Point from(320, 240); //Middle 
    Point to(639, 240); //Right border 
    arrowedLine(image, from, to, Vec3b(0, 0, 0), 1, LINE_AA, 0, 0.1); 
    imshow("Arrow", image); 
    waitKey(0); 
    return 0; 
} 

用箭頭畫出,但在尖端的一些像素丟失:

Arrow with missing tip pixels

爲了更精確,兩列像素沒有正確着色(縮放):

enter image description here

如果我禁用抗鋸齒,也就是說,如果我用

arrowedLine(image, from, to, Vec3b(0, 0, 0), 1, LINE_8, 0, 0.1); 

代替(注意LINE_8代替LINE_AA),像素都在那裏,雖然沒有抗鋸齒:

enter image description here

我意識到抗鋸齒可能依賴於相鄰像素,但看起來很奇怪的是,像素在邊界處根本不被繪製,而不是在沒有抗鋸齒的情況下繪製。有沒有解決這個問題的方法?

增加X座標,例如,到640或641)使問題變得更糟,即更多的箭頭像素消失,而尖端仍然缺少近兩個完整的像素列。

擴展和裁剪圖像將解決相鄰像素問題,但在我最初的使用案例中,出現問題的位置,我無法放大我的圖像,即其大小必須保持不變。

+0

你可以在邊界處有「之前」和「之後」的平均值 –

+0

@huseyintugrulbuyukisik:你的意思是我在有AA和沒有AA的情況下繪製箭頭,並取兩個受影響列的平均值? –

+0

我的意思是隻有邊界,而不是整個圖像 –

回答

2

經過快速審查,我發現OpenCV draws AA lines using a Gaussian filter,其中合同的最終形象。

正如我在評論中建議的那樣,您可以爲AA模式實現自己的功能(如果禁用AA,可以調用原始功能)手動擴展點(請參閱下面的代碼以獲得創意)。

其他選項可能會增加使用AA時的線寬。你也可以模擬OpenCV的AA效果,但是在最終的圖像上(如果你有很多箭頭,可能會更慢,但是很有幫助)。我不是專家OpenCV的,所以我會寫一個通用方案:

// Filter radius, the higher the stronger 
const int kRadius = 3; 

// Image is extended to fit pixels that are not going to be blurred 
Mat blurred(480 + kRadius * 2, 640 + kRadius * 2, CV_8UC3, Scalar(255, 255, 255)); 

// Points moved a according to filter radius (need testing, but the idea is that) 
Point from(320, 240 + kRadius); 
Point to(639 + kRadius * 2, 240 + kRadius); 

// Extended non-AA arrow 
arrowedLine(blurred, ..., LINE_8, ...); 

// Simulate AA 
GaussianBlur(blurred, blurred, Size(kRadius, kRadius), ...); 

// Crop image (be careful, it doesn't copy data) 
Mat image = blurred(Rect(kRadius, kRadius, 640, 480)); 

另一種選擇可能是繪製箭頭圖像的兩倍,規模下來了很好的平滑濾波器英寸

顯然,只有在圖像上沒有任何以前的數據時,最後兩個選項纔有效。如果是這樣,那麼使用透明圖像進行時間繪圖,並將其覆蓋在最後。

+0

感謝您的想法和努力,但是這需要重新分配原始圖像,即將其有效地移動到內存中,是否正確? –

+2

如果您正在手動執行將'BORDER_REPLICATE'傳遞給GaussianBlur的模糊效果,則應該給出更好的結果。有了這個標誌,它會選擇最後一列中的行的顏色。 –

+0

哦,我不知道這個選擇,太棒了! – cbuchart