Javascript Image Processing-edge gradient computing function _ javascript skills

Source: Internet
Author: User
In the previous article, we explained the expansion and corrosion functions in image processing. This article will provide edge gradient computing functions. If you are interested, you can learn more. Preface

In the previous article, we explained the expansion and corrosion functions in image processing. This article will provide edge gradient computing functions.

Image Edge

How is the image edge represented in mathematics?

On the edge of the image, the adjacent pixel value should be significantly changed. In mathematics, derivative represents a way to change the speed. A big change in the gradient value indicates a significant change in the image content.

Let's use a more vivid image to explain it. Suppose we have a one-dimensional image. The "jump" of the gray value in indicates the existence of the edge:

    

Using the first-order differential derivation, we can see the existence of the edge "jumping" more clearly (this shows a high peak value ):

    

From this we can conclude that the edge can be found by locating the phase element with the gradient value greater than the neighboring area.

Approximate Gradient

For example, when the kernel is 3.

First, calculate the approximate derivative of x:

Then, calculate the approximate derivative of the y direction:

Then calculate the gradient:

You can also write it as follows:

Function implementation

The Code is as follows:


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;
};


Here, only Sobel operators with the kernel size of 3 and 5 are provided. The main reason is that kernel computing with the kernel size of 7 or above is slow.
Output a 16-bit signed integer matrix of a single channel.

The Code is as follows:


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;
}
}
}


Then, the kernel and matrix are handed over to the filter for processing.

The reason for separating this filter is that it can be used by other similar computing edge functions, such as Laplacian and Scharr operators.

Convert to an unsigned 8-digit integer

Because the Sobel operator calculates a 16-bit signed integer and cannot be displayed as an image, we need a function to convert it into an unsigned 8-bit integer matrix.

The convertScaleAbs function is to take the absolute value of each element and put it in the Int8Array. because the number of values greater than 255 is automatically converted to 255, and the number smaller than 0 is automatically converted to 0, so we don't need to make a function to take charge of this job.

The Code is as follows:


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;
}

Merge values proportionally

We also need a function to overlay the gradient values in the x direction and the gradient values in the y direction.

The Code is as follows:


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;
};


This function is very simple. In fact, it only adds the corresponding elements of the two matrices in a fixed proportion.

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.