Javascript Image Processing-implementation principle of smooth processing _ javascript skills

Source: Internet
Author: User
Tags unsupported
Here, we directly reference the content of OpenCV2.4 + C ++ smooth processing and OpenCV2.4 + C ++ edge gradient computing, which is also called fuzzy. This is a simple and frequently used image processing method, for more information, see Preface

In the previous article, we explained the virtual edge of the image. This article begins to process the image smoothly (that is, blur.

Basic Principles

Here we directly reference OpenCV 2.4 + C ++ smooth processing and OpenCV 2.4 + C ++ edge gradient computing:

Smoothing, also known as fuzzy, is a simple and frequently used image processing method.

A filter is required for smooth processing.

. The most common filter is linear.

The output pixel value of linear filtering (for example, :) is the weighted average of input pixel values (for example:

    

Called Core

It is just a weighting coefficient.

This involves an operation called convolution. What is convolution?

Convolution is an operation between each image block and an operator (core.

Core ?!

Nbsp;
Dsds

The core is a fixed-size numeric array. This array has an anchor.

, Usually in the center of the array.

But how does this work?

If you want to obtain the convolution value at a specific position of the image, you can use the following method for calculation:

    Place the anchor of the core on the pixel at the specified position. At the same time, other values in the core overlap with the pixels in the pixel neighborhood. Each value in the core is multiplied by the corresponding pixel value, add the product and put the result on the pixel corresponding to the anchor. Repeat the above process on all pixels of the image.

The above process is shown in the formula as follows:

    

What should I do with convolution at the edge of the image?

Before calculating convolution, you need to create virtual pixels by copying the boundaries of the source image, so that there are enough pixels in the edge to calculate convolution. This is why virtual edge functions are required in the previous article.

Mean Smoothing

In fact, the mean smoothing is a convolution operation where all kernel elements are 1, and then divided by the kernel size. It is represented by a mathematical expression:

  

Below we will implement the mean smoothing function blur:

The Code is as follows:


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, CV_RGBA ),
DstData = dst. data;
Var size1 = _ size1 | 3,
Size2 = _ size2 | size1,
Size = size1 * size2;
If (size1% 2! = 1 | size2 % 2! = 1 ){
Console. error ("size must be an odd number ");
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 ("unsupported type. ");
}
Return dst;
}


Size1 and size2 are the horizontal and vertical sizes of the core, and must be positive odd numbers.

Gaussian smoothing

The most useful filter (though not the fastest ). Gaussian filter combines each pixel of the input array with the Gaussian Kernel.

Convolution uses convolution and as the output pixel value.

By referring to the one-dimensional Gaussian function, we can see that it is a function with both sides of the middle.

Therefore, the weighted number of Gaussian filters is large in the middle and small in four weeks.

The second-dimension Gaussian function is:

    

Where

Is the mean (peak position ),

Represents the standard deviation (Variable

And Variables

Each has an mean and a standard deviation ).

See the implementation of OpenCV here, but there should be room for optimization, because it is not used to separate the filter.

First, we create a getGaussianKernel to return the one-dimensional array of Gaussian filter.

The Code is as follows:


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 );
Kernel [I] = t;
Sum + = t;
}

Sum = 1/sum;

For (I = _ n; I --;){
Kernel [I] * = sum;
}

Return kernel;
};


Then we can use two one-dimensional arrays to calculate a complete Gaussian Kernel. Then we can use the cyclic method used in blur to calculate the Gaussian smoothing matrix.

The Code is as follows:


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, CV_RGBA ),
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 must be an odd number. ");
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 ("unsupported type ");
}
Return dst;
}

Median Smoothing

The median filter uses the neighborhood (Square area centered on the current pixel) for each pixel of the image.

Median.

Still use the loop used in blur. You only need to obtain all values in the core and then sort them by sort to obtain the value. Then, the anchor is replaced by this value.

The Code is as follows:


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, CV_RGBA ),
DstData = dst. data;
Var size1 = _ size1 | 3,
Size2 = _ size2 | size1,
Size = size1 * size2;
If (size1% 2! = 1 | size2 % 2! = 1 ){
Console. error ("size must be an odd number ");
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 ("type not supported ");
}
Return dst;
};

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.