Home >Web Front-end >JS Tutorial >Javascript image processing—image morphology (expansion and erosion)_javascript skills

Javascript image processing—image morphology (expansion and erosion)_javascript skills

WBOY
WBOYOriginal
2016-05-16 17:44:361891browse
Foreword

In the previous article , we explained the threshold function in image processing. In this article we will do the expansion and corrosion functions.

Expansion and Corrosion

The concept may be difficult to explain. Let’s take a look at the pictures. The first is the original picture:

Original image

After expansion it will look like this:

Dilation result - Theory example

After corrosion, it will look like this:

Erosion result - Theory example

It may seem a little puzzling. It is obvious that it is expansion, but why the words become thinner, and it is obvious that it is corrosion, why does the word become thicker?

Actually, the so-called expansion should refer to :

Brighter color blocks expand.

The so-called corrosion should refer to :

Brighter color blocks corrode.

In the picture above, since the white background is a lighter color block, when it expands, it flattens the words on the darker black block... On the contrary, when it corrodes, the words absorb water and expand...

expressed as a mathematical formula is :

To put it bluntly, it is to find the darkest or brightest pixel in the kernel of a specified size, and replace the pixel on the kernel anchor point with this point.

Achieve

First we implement the expansion dilate function.

Copy code The code is as follows:

var dilate = function(__src, __size, __borderType, __dst ){
__src || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type == "CV_RGBA"){
var width = __src .col,
height = __src.row,
size = __size || 3,
dst = __dst || new Mat(height, width, CV_RGBA),
dstData = dst.data;

var start = size >> 1;
var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType),
mData = withBorderMat.data,
mWidth = withBorderMat.col;

var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;

if(size & 1 === 0){
error(arguments .callee, UNSPPORT_SIZE/* {line} */);
return __src;
}

for(i = height; i--;){
offsetI = i * width;
for(j = width; j--;){
newOffset = 0;
total = 0;
for(y = size; y--;){
offsetY = ( y i) * mWidth * 4;
for(x = size; x--;){
nowX = (x j) * 4;
nowOffset = offsetY nowX;
(mData[nowOffset] mData [nowOffset 1] mData[nowOffset 2] > total) && (total = mData[nowOffset] mData[nowOffset 1] mData[nowOffset 2]) && (newOffset = nowOffset);
}
}
dstData[(j offsetI) * 4] = mData[newOffset];
dstData[(j offsetI) * 4 1] = mData[newOffset 1];
dstData[(j offsetI) * 4 2] = mData [newOffset 2];
dstData[(j offsetI) * 4 3] = mData[newOffset 3];
}
}

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

In this line of code, we first use the RGB value and the previous one Compare the maximum value total, and then if the new value is larger, assign the new value to total, and assign the new offset newOffset to the current offset nowOffset.

Then after the entire kernel-sized area is cycled, a maximum total and the corresponding offset newOffset can be found. You can assign the value:

dstData[(j offsetI) * 4] = mData[newOffset];
dstData[(j offsetI) * 4 1] = mData[newOffset 1];
dstData[(j offsetI) * 4 2 ] = mData[newOffset 2];
dstData[(j offsetI) * 4 3] = mData[newOffset 3];

Then the erosion function is the opposite, just find the smallest value.

Copy code The code is as follows:

var erode = function(__src, __size, __borderType, __dst){
__src || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type == "CV_RGBA"){
var width = __src.col,
height = __src.row,
size = __size || 3,
dst = __dst || new Mat(height, width, CV_RGBA),
dstData = dst.data;

var start = size >> 1;
var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType),
mData = withBorderMat.data,
mWidth = withBorderMat.col;

var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;

if(size & 1 === 0){
error(arguments.callee, UNSPPORT_SIZE/* {line} */);
return __src;
}

for(i = height; i--;){
offsetI = i * width;
for(j = width; j--;){
newOffset = 0;
total = 765;
for(y = size; y--;){
offsetY = (y i) * mWidth * 4;
for(x = size; x--;){
nowX = (x j) * 4;
nowOffset = offsetY nowX;
(mData[nowOffset] mData[nowOffset 1] mData[nowOffset 2] < total) && (total = mData[nowOffset] mData[nowOffset 1] mData[nowOffset 2]) && (newOffset = nowOffset);
}
}
dstData[(j offsetI) * 4] = mData[newOffset];
dstData[(j offsetI) * 4 1] = mData[newOffset 1];
dstData[(j offsetI) * 4 2] = mData[newOffset 2];
dstData[(j offsetI) * 4 3] = mData[newOffset 3];
}
}

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

效果

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn