簡體   English   中英

如何從位圖區域獲取多邊形形狀

[英]How do I get a polygon shape from a bitmap area

所以-這是在少數情況下,我問一個“我怎么做”問題的地方,在這里我實際上什么都沒嘗試過,因為我不知道從哪里開始。

這是我的問題。

我有一張在綠色屏幕上鎖定的照片,然后變成了蒙版,其中有一些透明的像素,其余的是黑色的。 假設這個黑色形狀是攝影對象的上胸部和頭部。

我知道如何找到所有黑色像素,並且我可以輕松找出哪些黑色像素與透明像素相鄰,這樣我就可以輕松繪制出黑色形狀的輪廓,但是那是我的想法用光了……如何轉換它輪廓成點的連續數組,可以用作多邊形?

完成我的分析后,我已經從蒙版位圖創建了SVG矢量路徑。 這為輪廓框架中所有點提供了優化的序列路徑。

將矢量輪廓轉換為位圖的過程稱為渲染。 將位圖轉換為輪廓的相反過程稱為跟蹤。

適用的其他標簽:蒙版,矢量圖形,矢量化,矢量,跟蹤,貝塞爾曲線,貝塞爾曲線...

鏈接:
理論PDF Potrace:基於多邊形的跟蹤算法
Potrace維基
Potrace Android端口和前端
第一步很簡單,將綠色屏幕(色鍵)替換為alpha。 我將創建一個遮罩,將其解析為向量SVG
到目前為止,我有:
圖像1是原始圖像(綠屏)[色鍵]。 圖2綠屏替換為Alpha蒙版。
原版的 α 圖3輪廓框架(作為Alpha的位圖) 圖4遮罩。
輪廓 面具
圖片5這是SVG矢量文件的輪廓(將以下文本保存到svg.svg文件中,然后將其加載到瀏覽器中以對其進行驗證; O)[外觀類似於圖3]。

<svg width="320" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created by Jon Goodwin maskActivity version 1.1.2" >
<path desc="l 0 p 0" fill="rgb(255,255,255)" stroke="rgb(0,0,0)" stroke-width="1" opacity="1.0"
d="M 125.5 13.0 L 136.0 13.5 L 145.5 15.0 L 157.5 18.0 L 166.5 23.0 L 176.5 30.0 Q 184.4 32.1 188.0 38.5 L 196.0 50.5 Q 194.8 56.3 198.0 57.5 
L 201.5 65.0 L 205.0 73.5 L 207.0 77.5 L 207.0 84.5 L 206.5 86.0 L 210.0 88.5 L 209.0 91.5 L 215.0 93.5 Q 219.7 98.3 219.0 108.5 L 218.0 111.5 
L 218.0 120.5 L 217.0 127.5 L 216.0 129.5 Q 216.5 134.5 212.5 135.0 L 208.0 136.5 L 208.0 149.5 Q 206.8 154.3 209.0 155.5 L 210.5 162.0 
L 214.5 163.0 L 218.0 165.5 Q 219.8 168.8 224.5 169.0 L 238.5 176.0 L 250.5 184.0 L 266.5 193.0 L 278.5 200.0 L 283.5 203.0 L 295.0 212.5 
L 295.5 214.0 L 299.0 216.5 L 306.0 226.5 L 308.5 231.0 L 312.0 239.5 L 66.5 240.0 L 66.0 237.5 L 68.0 234.5 
L 69.0 227.5 Q 72.6 226.1 72.5 221.0 L 78.0 214.5 L 91.5 199.0 L 96.5 198.0 L 102.0 195.5 L 104.5 192.0 L 106.0 191.5 L 103.0 185.5 
L 101.0 180.5 Q 102.0 172.5 97.5 170.0 L 94.0 167.5 L 84.5 132.0 L 84.0 124.5 Q 84.8 120.8 82.5 120.0 Q 80.3 119.3 81.0 115.5 L 82.0 112.5 
L 81.0 109.5 L 81.0 102.5 L 82.0 99.5 L 82.0 93.5 L 81.0 89.5 L 83.0 84.5 L 81.5 85.0 Q 77.5 85.5 77.0 82.5 L 78.0 70.5 Q 77.1 62.1 80.0 57.5 
Q 77.3 56.8 78.0 52.5 Q 79.6 45.5 84.5 42.0 L 86.0 41.5 Q 85.3 37.8 87.5 37.0 L 93.5 31.0 L 95.0 30.5 L 101.5 19.0 Q 106.3 20.3 107.5 18.0 
L 111.5 17.0 L 125.5 13.0 Z" />
</svg>


關於SVG的注意事項:SVG中的路徑具有緊湊的編碼。 例如,M(用於“移動到”)在初始數值x和y坐標之前,而L(行至)在應該繪制線的點之前。 其他命令字母(C,S,Q,T和A)位於用於繪制各種貝塞爾曲線和橢圓曲線的數據之前。 Q是二次貝塞爾曲線,Z用於閉合路徑。 在所有情況下,絕對坐標都遵循大寫字母命令,而相對坐標用於等效的小寫字母之后。

輪廓框架 有點棘手 (我發現了一些編碼魔術)。 它是一個位圖,圖像的所有白色部分都為一個alpha。 實際上,連續的線輪廓框架中有幾種顏色(可以)。
(我們[I] ,; O |)現在可能正接近問題的核心 ;; O))
你說:

我可以輕松地繪制出黑色形狀的輪廓 ,但這就是我的想法用盡的地方……如何將輪廓轉換成可以用作多邊形的點的順序陣列

嗯,很棘手 (取決於您想要的多邊形,我在想像是SVG矢量圖形將為我們提供來自掩碼位圖的點序列),但它是封閉的連續且循環的(沒有孔,並且只有一條線),還不錯

沒有外部庫或依賴項。
這是changeColor()代碼( 圖像1圖像2 ):
這樣稱呼:

Bitmap chromoBmp       = changeColor(origBmp, 0xff00FF00, 0x00000000, false, "chromo");//green to alpha


private Bitmap changeColor(Bitmap src, int colorToReplace, int colorThatWillReplace, boolean not, String log) {
    int width = src.getWidth();
    int height = src.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
    src.getPixels(pixels, 0, width, 0, 0, width, height);

Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
int pixel;

 // iteration through pixels
for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
        // get current index in 2D-matrix
        int index = y * width + x;
        pixel = pixels[index];

        if(not == true)
        {
            if(pixel != colorToReplace)
            {
                pixels[index] = colorThatWillReplace;
            }
        }
        else
        {
            if(pixel == colorToReplace)
            {
                pixels[index] = colorThatWillReplace;
            }
        }
    }//x
}//y

bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
}

還有一些非常重要的(魔術) processingBitmap_BlurContour() Bitmap_BlurContour processingBitmap_BlurContour() (從Image2Image3 ):
這樣稱呼:

Bitmap framContourBmp  = processingBitmap_BlurContour(changedBmp, 1);//thickness of frame


private Bitmap processingBitmap_BlurContour(Bitmap src, int blurValue){
    int width = src.getWidth();
    int height = src.getHeight();

BlurMaskFilter blurMaskFilter;
Paint paintBlur = new Paint();

Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);//***VERY IMPORTANT Bitmap.Config.RGB_565 **NOT** Bitmap.Config.ARGB_8888
Canvas canvas = new Canvas(dest);

//Create background in Black
Bitmap alpha = src.extractAlpha();
paintBlur.setColor(0xFF00FF00);//green with alpha set to FF
canvas.drawBitmap(alpha, 0, 0, paintBlur);

//Create outer blur, in Black
blurMaskFilter = new BlurMaskFilter(blurValue, BlurMaskFilter.Blur.OUTER);
paintBlur.setMaskFilter(blurMaskFilter);
canvas.drawBitmap(alpha, 0, 0, paintBlur);

//Create inner blur
blurMaskFilter = new BlurMaskFilter(blurValue, BlurMaskFilter.Blur.INNER);
paintBlur.setMaskFilter(blurMaskFilter);
canvas.drawBitmap(src, 0, 0, paintBlur);

return dest;
   }//processingBitmap_BlurContour

要制作位圖蒙版(從Image2Image4 ):

Bitmap changedBmp = changeColor(bmp, 0,  0xff000000, true, "mask");//any col NOT trans(black) -> opaque black

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM