打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Javascript图像处理之平滑处理
/* * BORDER_REPLICATE:     aaaaaaaa|abcdefgh|hhhhhhhh * BORDER_REFLECT:       hgfedcba|abcdefgh|hgfedcba * BORDER_REFLECT_101:   hgfedcb|abcdefgh|gfedcba * BORDER_WRAP:          efgh|abcdefgh|abcd * BORDER_CONSTANT:      iiiiiiii|abcdefgh|iiiiiiii  with some specified 'i'(default value [0, 0, 0, 255])*/(function () {    function imageBlur(iCanvas, url, borderType, orientation, blurType, value) {        this.canvas = iCanvas;        this.iCtx = this.canvas.getContext("2d");        this.url = url;        this.borderType = borderType;        this.orientation = orientation || "bottom";        this.value = value || [0, 0, 0, 255];        this.blurType = blurType || "blur";    }    imageBlur.prototype = {        imread: function (_image) {            var width = _image.width,                height = _image.height;            this.iResize(width, height);            this.iCtx.drawImage(_image, 0, 0);            var imageData = this.iCtx.getImageData(0, 0, width, height),                tempMat = new Mat(height, width, imageData.data);            imageData = null;            this.iCtx.clearRect(0, 0, width, height);            return tempMat;        },        iResize: function (_width, _height) {            this.canvas.width = _width;            this.canvas.height = _height;        },        RGBA2ImageData: function (_imgMat) {            var width = _imgMat.col,                height = _imgMat.row;            var imageData = this.iCtx.createImageData(width, height);            imageData.data.set(_imgMat.data);            return imageData;        },        render: function () {            var img = new Image();            var _this = this;            img.onload = function () {                var myMat = _this.imread(img);                var newImage = null;                if (_this.blurType == "blur") {                    newImage = blur(myMat, 11, 11, _this.borderType);                } else if (_this.blurType == "median") {                    newImage = medianBlur(myMat, 11, 11, _this.borderType);                } else {                    newImage = GaussianBlur(myMat, 11, 11, 0, 0, _this.borderType);                }                var newIamgeData = _this.RGBA2ImageData(newImage);                _this.iCtx.putImageData(newIamgeData, 0, 0);            };            img.src = this.url;        }    };    function Mat(_row, _col, _data, _buffer) {        this.row = _row || 0;        this.col = _col || 0;        this.channel = 4;        this.buffer = _buffer || new ArrayBuffer(_row * _col * 4);        this.data = new Uint8ClampedArray(this.buffer);        _data && this.data.set(_data);        this.bytes = 1;        this.type = "CV_RGBA";    }    function blur(__src, __size1, __size2, __borderType, __dst) {        if (__src.type && __src.type == "CV_RGBA") {            var height = __src.row,                width = __src.col,                dst = __dst || new Mat(height, width, __src.data),                dstData = dst.data;            var size1 = __size1 || 3,                size2 = __size2 || size1,                size = size1 * size2;            if (size1 % 2 !== 1 || size2 % 2 !== 1) {                console.error("size大小必须是奇数");                return __src;            }            var startX = Math.floor(size1 / 2),                startY = Math.floor(size2 / 2);            var withBorderMat = copyMakeBorder(__src, startY, startX, 0, 0, __borderType),                mData = withBorderMat.data,                mWidth = withBorderMat.col;            var newValue, nowX, offsetY, offsetI;            var i, j, c, y, x;            for (i = height; i--;) {                offsetI = i * width;                for (j = width; j--;) {                    for (c = 3; c--;) {                        newValue = 0;                        for (y = size2; y--;) {                            offsetY = (y + i) * mWidth * 4;                            for (x = size1; x--;) {                                nowX = (x + j) * 4 + c;                                newValue += mData[offsetY + nowX];                            }                        }                        dstData[(j + offsetI) * 4 + c] = newValue / size;                    }                    dstData[(j + offsetI) * 4 + 3] = mData[offsetY + startY * mWidth * 4 + (j + startX) * 4 + 3];                }            }        } else {            console.error("不支持类型。");        }        return dst;    }    function getGaussianKernel(__n, __sigma) {        var SMALL_GAUSSIAN_SIZE = 7,            smallGaussianTab = [[1],                                [0.25, 0.5, 0.25],                                [0.0625, 0.25, 0.375, 0.25, 0.0625],                                [0.03125, 0.109375, 0.21875, 0.28125, 0.21875, 0.109375, 0.03125]            ];        var fixedKernel = __n & 2 == 1 && __n <= SMALL_GAUSSIAN_SIZE && __sigma <= 0 ? smallGaussianTab[__n >> 1] : 0;        var sigmaX = __sigma > 0 ? __sigma : ((__n - 1) * 0.5 - 1) * 0.3 + 0.8,            scale2X = -0.5 / (sigmaX * sigmaX),            sum = 0;        var i, x, t, kernel = [];        for (i = 0; i < __n; i++) {            x = i - (__n - 1) * 0.5;            t = fixedKernel ? fixedKernel[i] : Math.exp(scale2X * x * x);            kernel[i] = t;            sum += t;        }        sum = 1 / sum;        for (i = __n; i--;) {            kernel[i] *= sum;        }        return kernel;    };    function GaussianBlur(__src, __size1, __size2, __sigma1, __sigma2, __borderType, __dst) {        if (__src.type && __src.type == "CV_RGBA") {            var height = __src.row,                width = __src.col,                dst = __dst || new Mat(height, width, __src.data),                dstData = dst.data;            var sigma1 = __sigma1 || 0,                sigma2 = __sigma2 || __sigma1;            var size1 = __size1 || Math.round(sigma1 * 6 + 1) | 1,                size2 = __size2 || Math.round(sigma2 * 6 + 1) | 1,                size = size1 * size2;            if (size1 % 2 !== 1 || size2 % 2 !== 1) {                console.error("size必须是奇数。");                return __src;            }            var startX = Math.floor(size1 / 2),                startY = Math.floor(size2 / 2);            var withBorderMat = copyMakeBorder(__src, startY, startX, 0, 0, __borderType),                mData = withBorderMat.data,                mWidth = withBorderMat.col;            var kernel1 = getGaussianKernel(size1, sigma1),                kernel2,                kernel = new Array(size1 * size2);            if (size1 === size2 && sigma1 === sigma2)                kernel2 = kernel1;            else                kernel2 = getGaussianKernel(size2, sigma2);            var i, j, c, y, x;            for (i = kernel2.length; i--;) {                for (j = kernel1.length; j--;) {                    kernel[i * size1 + j] = kernel2[i] * kernel1[j];                }            }            var newValue, nowX, offsetY, offsetI;            for (i = height; i--;) {                offsetI = i * width;                for (j = width; j--;) {                    for (c = 3; c--;) {                        newValue = 0;                        for (y = size2; y--;) {                            offsetY = (y + i) * mWidth * 4;                            for (x = size1; x--;) {                                nowX = (x + j) * 4 + c;                                newValue += (mData[offsetY + nowX] * kernel[y * size1 + x]);                            }                        }                        dstData[(j + offsetI) * 4 + c] = newValue;                    }                    dstData[(j + offsetI) * 4 + 3] = mData[offsetY + startY * mWidth * 4 + (j + startX) * 4 + 3];                }            }        } else {            console.error("不支持的类型");        }        return dst;    }    function medianBlur(__src, __size1, __size2, __borderType, __dst) {        if (__src.type && __src.type == "CV_RGBA") {            var height = __src.row,                width = __src.col,                dst = __dst || new Mat(height, width, __src.data),                dstData = dst.data;            var size1 = __size1 || 3,                size2 = __size2 || size1,                size = size1 * size2;            if (size1 % 2 !== 1 || size2 % 2 !== 1) {                console.error("size必须是奇数");                return __src;            }            var startX = Math.floor(size1 / 2),                startY = Math.floor(size2 / 2);            var withBorderMat = copyMakeBorder(__src, startY, startX, 0, 0, __borderType),                mData = withBorderMat.data,                mWidth = withBorderMat.col;            var newValue = [], nowX, offsetY, offsetI;            var i, j, c, y, x;            for (i = height; i--;) {                offsetI = i * width;                for (j = width; j--;) {                    for (c = 3; c--;) {                        for (y = size2; y--;) {                            offsetY = (y + i) * mWidth * 4;                            for (x = size1; x--;) {                                nowX = (x + j) * 4 + c;                                newValue[y * size1 + x] = mData[offsetY + nowX];                            }                        }                        newValue.sort();                        dstData[(j + offsetI) * 4 + c] = newValue[Math.round(size / 2)];                    }                    dstData[(j + offsetI) * 4 + 3] = mData[offsetY + startY * mWidth * 4 + (j + startX) * 4 + 3];                }            }        } else {            console.error("类型不支持");        }        return dst;    };    function copyMakeBorder(_src, _top, _left, _bottom, _right, _borderType, _value) {        if (_src.type != "CV_RGBA") {            console.log("not support this type");        } else if (_borderType == "BORDER_CONSTANT") {            return copyMakeConstBorder_8U(_src, _top, _left, _bottom, _right, _value);        } else {            return copyMakeBorder_8U(_src, _top, _left, _bottom, _right, _borderType);        }    }    function borderInterpolate(_p, _len, _borderType) {        if (_p < 0 || _p >= _len) {            switch (_borderType) {                case "BORDER_REPLICATE":                    _p = _p < 0 ? 0 : _len - 1;                    break;                case "BORDER_REFLECT":                case "BORDER_REFLECT_101":                    var delta = (_borderType == "BORDER_REFLECT_101");                    if (_len == 1) {                        return 0;                    }                    do {                        if (_p < 0) {                            _p = -_p - 1 + delta;                        } else {                            _p = _len - 1 - (_p - _len) - delta;                        }                    } while (_p < 0 || _p >= _len);                    break;                case "BORDER_WRAP":                    if (_p < 0) {                        _p -= ((_p - _len + 1) / _len | 0) * _len;                    }                    if (_p >= _len) {                        _p %= _len;                    }                    break;                case "BORDER_CONSTANT":                    _p = -1;                default:                    console.log(arguments.callee, "UNSPPORT_BORDER_TYPE");            }        }        return _p;    }    function copyMakeBorder_8U(_src, _top, _left, _bottom, _right, _borderType) {        var i, j;        var width = _src.col,            height = _src.row;        var top = _top,            left = _left || _top,            right = _right || left,            bottom = _bottom || top,            dstWidth = width + left + right,            dstHeight = height + top + bottom,            borderType = _borderType || "BORDER_REFLECT";        var buffer = new ArrayBuffer(dstHeight * dstWidth * 4),            tab = new Uint32Array(left + right);        for (i = 0; i < left; i++) {            tab[i] = borderInterpolate(i - left, width, borderType);        }        for (i = 0; i < right; i++) {            tab[i + left] = borderInterpolate(width + i, width, borderType);        }        var tempArray, data;        for (i = 0; i < height; i++) {            tempArray = new Uint32Array(buffer, (i + top) * dstWidth * 4, dstWidth);            data = new Uint32Array(_src.buffer, i * width * 4, width);            for (j = 0; j < left; j++)                tempArray[j] = data[tab[j]];            for (j = 0; j < right; j++)                tempArray[j + width + left] = data[tab[j + left]];            tempArray.set(data, left);        }        var allArray = new Uint32Array(buffer);        for (i = 0; i < top; i++) {            j = borderInterpolate(i - top, height, _borderType);            tempArray = new Uint32Array(buffer, i * dstWidth * 4, dstWidth);            tempArray.set(allArray.subarray((j + top) * dstWidth, (j + top + 1) * dstWidth));        }        for (i = 0; i < bottom; i++) {            j = borderInterpolate(i + height, height, borderType);            tempArray = new Uint32Array(buffer, (i + top + height) * dstWidth * 4, dstWidth);            tempArray.set(allArray.subarray((j + top) * dstWidth, (j + top + 1) * dstWidth));        }        return new Mat(dstHeight, dstWidth, new Uint8ClampedArray(buffer));    }    function copyMakeConstBorder_8U(_src, _top, _left, _bottom, _right, _value) {        var i, j;        var width = _src.col,            height = _src.row;        var top = _top,            left = _left || _top,            right = _right || left,            bottom = _bottom || top,            dstWidth = width + left + right,            dstHeight = height + top + bottom,            value = _value || [0, 0, 0, 255];        var constBuf = new ArrayBuffer(dstWidth * 4),            constArray = new Uint8ClampedArray(constBuf);        buffer = new ArrayBuffer(dstHeight * dstWidth * 4);        for (i = 0; i < dstWidth; i++) {            for (j = 0; j < 4; j++) {                constArray[i * 4 + j] = value[j];            }        }        constArray = new Uint32Array(constBuf);        var tempArray;        for (i = 0; i < height; i++) {            tempArray = new Uint32Array(buffer, (i + top) * dstWidth * 4, left);            tempArray.set(constArray.subarray(0, left));            tempArray = new Uint32Array(buffer, ((i + top + 1) * dstWidth - right) * 4, right);            tempArray.set(constArray.subarray(0, right));            tempArray = new Uint32Array(buffer, ((i + top) * dstWidth + left) * 4, width);            tempArray.set(new Uint32Array(_src.buffer, i * width * 4, width));        }        for (i = 0; i < top; i++) {            tempArray = new Uint32Array(buffer, i * dstWidth * 4, dstWidth);            tempArray.set(constArray);        }        for (i = 0; i < bottom; i++) {            tempArray = new Uint32Array(buffer, (i + top + height) * dstWidth * 4, dstWidth);            tempArray.set(constArray);        }        return new Mat(dstHeight, dstWidth, new Uint8ClampedArray(buffer));    }    window.imageBlur = imageBlur;})();




https://www.cnblogs.com/artwl/archive/2013/01/22/2872355.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ScrollView中让图片保持居中
房间最新广播代码
【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
精典UC房间广播代码
OpenCV3学习(4.2)
【OpenCV入门教程之八】线性邻域滤波专场:方框滤波、均值滤波与高斯滤波
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服