<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        javascript圖像處理—邊緣梯度計算函數_javascript技巧

        來源:懂視網 責編:小采 時間:2020-11-27 21:06:44
        文檔

        javascript圖像處理—邊緣梯度計算函數_javascript技巧

        javascript圖像處理—邊緣梯度計算函數_javascript技巧:前言 上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數,這篇文章將做邊緣梯度計算函數。 圖像的邊緣 圖像的邊緣從數學上是如何表示的呢? 圖像的邊緣上,鄰近的像素值應當顯著地改變了。而在數學上,導數是表示改變快慢的一種方法。梯度值的大變預示著圖
        推薦度:
        導讀javascript圖像處理—邊緣梯度計算函數_javascript技巧:前言 上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數,這篇文章將做邊緣梯度計算函數。 圖像的邊緣 圖像的邊緣從數學上是如何表示的呢? 圖像的邊緣上,鄰近的像素值應當顯著地改變了。而在數學上,導數是表示改變快慢的一種方法。梯度值的大變預示著圖

        前言

        上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數,這篇文章將做邊緣梯度計算函數。

        圖像的邊緣

        圖像的邊緣從數學上是如何表示的呢?

        How intensity changes in an edge

        圖像的邊緣上,鄰近的像素值應當顯著地改變了。而在數學上,導數是表示改變快慢的一種方法。梯度值的大變預示著圖像中內容的顯著變化了。

        用更加形象的圖像來解釋,假設我們有一張一維圖形。下圖中灰度值的“躍升”表示邊緣的存在:

            Intensity Plot for an edge

        使用一階微分求導我們可以更加清晰的看到邊緣“躍升”的存在(這里顯示為高峰值):

            First derivative of Intensity - Plot for an edge

        由此我們可以得出:邊緣可以通過定位梯度值大于鄰域的相素的方法找到。

        近似梯度

        比如內核為3時。

        首先對x方向計算近似導數:

        G_{x} = \begin{bmatrix}-1 & 0 & +1 \\-2 & 0 & +2 \\-1 & 0 & +1\end{bmatrix} * I

        然后對y方向計算近似導數:

        G_{y} = \begin{bmatrix}-1 & -2 & -1 \\0 & 0 & 0 \\+1 & +2 & +1\end{bmatrix} * I

        然后計算梯度:

        G = \sqrt{ G_{x}^{2} + G_{y}^{2} }

        當然你也可以寫成:

        G = |G_{x}| + |G_{y}|

        函數實現
        代碼如下:
        var Sobel = function(__src, __xorder, __yorder, __size, __borderType, __dst){
        (__src && (__xorder ^ __yorder)) || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
        if(__src.type && __src.type === "CV_GRAY"){
        var kernel1,
        kernel2,
        height = __src.row,
        width = __src.col,
        dst = __dst || new Mat(height, width, CV_16I, 1),
        dstData = dst.data
        size = __size || 3;
        switch(size){
        case 1:
        size = 3;
        case 3:
        if(__xorder){
        kernel = [-1, 0, 1,
        -2, 0, 2,
        -1, 0, 1
        ];
        }else if(__yorder){
        kernel = [-1, -2, -1,
        , 0, 0,
        , 2, 1
        ];
        }
        break;
        case 5:
        if(__xorder){
        kernel = [-1, -2, 0, 2, 1,
        -4, -8, 0, 8, 4,
        -6,-12, 0,12, 6,
        -4, -8, 0, 8, 4,
        -1, -2, 0, 2, 1
        ];
        }else if(__yorder){
        kernel = [-1, -4, -6, -4, -1,
        -2, -8,-12, -8, -2,
        , 0, 0, 0, 0,
        , 8, 12, 8, 2,
        , 4, 6, 4, 1
        ];
        }
        break;
        default:
        error(arguments.callee, UNSPPORT_SIZE/* {line} */);

        }

        GRAY216IC1Filter(__src, size, height, width, kernel, dstData, __borderType);

        }else{
        error(arguments.callee, UNSPPORT_DATA_TYPE/* {line} */);
        }
        return dst;
        };

        這里只提供了內核大小為3和5的Sobel算子,主要原因是7或以上的內核計算就比較慢了。
        輸出一個單通道的16位有符號整數矩陣。
        代碼如下:
        function GRAY216IC1Filter(__src, size, height, width, kernel, dstData, __borderType){
        var start = size >> 1;

        var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType);

        var mData = withBorderMat.data,
        mWidth = withBorderMat.col;

        var i, j, y, x, c;
        var newValue, nowX, offsetY, offsetI;

        for(i = height; i--;){
        offsetI = i * width;
        for(j = width; j--;){
        newValue = 0;
        for(y = size; y--;){
        offsetY = (y + i) * mWidth;
        for(x = size; x--;){
        nowX = x + j;
        newValue += (mData[offsetY + nowX] * kernel[y * size + x]);
        }
        }
        dstData[j + offsetI] = newValue;
        }
        }
        }

        然后把內核和矩陣交給這個濾波器處理,就OK了。

        把這個濾波器獨立出來的原因是,可以給其他類似的計算邊緣函數使用,比如Laplacian和Scharr算子。

        轉為無符號8位整數

        由于Sobel算子算出來的是16位有符號整數,無法顯示成圖片,所以我們需要一個函數來將其轉為無符號8位整數矩陣。

        convertScaleAbs函數是將每個元素取絕對值,然后放到Int8Array數組里面,由于在賦值時候大于255的數會自動轉成255,而小于0的數會自動轉成0,所以不需要我們做一個函數來負責這一工作。
        代碼如下:
        function convertScaleAbs(__src, __dst){
        __src || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
        var height = __src.row,
        width = __src.col,
        channel = __src.channel,
        sData = __src.data;

        if(!__dst){
        if(channel === 1)
        dst = new Mat(height, width, CV_GRAY);
        else if(channel === 4)
        dst = new Mat(height, width, CV_RGBA);
        else
        dst = new Mat(height, width, CV_8I, channel);
        }else{
        dst = __dst;
        }

        var dData = dst.data;

        var i, j, c;

        for(i = height; i--;){
        for(j = width * channel; j--;){
        dData[i * width * channel + j] = Math.abs(sData[i * width * channel + j]);
        }
        }

        return dst;
        }

        按比例合并值

        我們還需要一個函數將x方向梯度計算值和y方向梯度計算值疊加起來。
        代碼如下:
        var addWeighted = function(__src1, __alpha, __src2, __beta, __gamma, __dst){
        (__src1 && __src2) || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
        var height = __src1.row,
        width = __src1.col,
        alpha = __alpha || 0,
        beta = __beta || 0,
        channel = __src1.channel,
        gamma = __gamma || 0;
        if(height !== __src2.row || width !== __src2.col || channel !== __src2.channel){
        error(arguments.callee, "Src2 must be the same size and channel number as src1!"/* {line} */);
        return null;
        }

        if(!__dst){
        if(__src1.type.match(/CV\_\d+/))
        dst = new Mat(height, width, __src1.depth(), channel);
        else
        dst = new Mat(height, width, __src1.depth());
        }else{
        dst = __dst;
        }

        var dData = dst.data,
        s1Data = __src1.data,
        s2Data = __src2.data;

        var i;

        for(i = height * width * channel; i--;)
        dData[i] = __alpha * s1Data[i] + __beta * s2Data[i] + gamma;

        return dst;
        };

        這個函數很簡單,實際上只是對兩個矩陣的對應元素按固定比例相加而已。 效果圖

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        javascript圖像處理—邊緣梯度計算函數_javascript技巧

        javascript圖像處理—邊緣梯度計算函數_javascript技巧:前言 上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數,這篇文章將做邊緣梯度計算函數。 圖像的邊緣 圖像的邊緣從數學上是如何表示的呢? 圖像的邊緣上,鄰近的像素值應當顯著地改變了。而在數學上,導數是表示改變快慢的一種方法。梯度值的大變預示著圖
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲无码视频在线| 99在线免费视频| 大地影院MV在线观看视频免费| 免费视频中文字幕| 免费国产在线精品一区| 99在线精品免费视频九九视| 大学生一级毛片免费看| 亚洲AV色香蕉一区二区| 国产gv天堂亚洲国产gv刚刚碰| 免费大黄网站在线观看| 亚洲午夜一区二区电影院| 国产成人精品一区二区三区免费| xxxxx做受大片视频免费| 毛片免费全部免费观看| 亚洲精品在线免费观看| 久久精品国产亚洲av麻| 一级**爱片免费视频| 亚洲AV无码乱码在线观看牲色| 亚洲人成色在线观看| 在线免费视频一区| 亚洲精品无码专区在线播放| 嫩草视频在线免费观看| 亚洲人成77777在线播放网站不卡| 免免费国产AAAAA片| 国产成人精品免费视| 亚洲伦理一二三四| 男女免费观看在线爽爽爽视频 | yy6080久久亚洲精品| 国产亚洲精品a在线观看| 一区免费在线观看| 久久乐国产精品亚洲综合| 一级做a爰片久久免费| 亚洲精品无码专区在线在线播放 | 亚洲综合av一区二区三区| 亚洲精品无播放器在线播放| 成人性生交大片免费看午夜a| 亚洲人成网站看在线播放| 在线免费不卡视频| 大地资源在线资源免费观看| 亚洲熟伦熟女专区hd高清| 久久99亚洲综合精品首页|