Binarization of images
Image binarization is to set the gray value of pixels on the image to 0 or 255, that is, the whole image presents an obvious black and white effect. The binarization images with 256 luminance levels can be obtained by selecting appropriate thresholds which can still reflect the whole and local features of the image. In digital image processing, binary image plays a very important role. First of all, the binary image is conducive to further image processing, making the image simple, and the amount of data is reduced, which can highlight the outline of the target of interest. Secondly, to carry on the binary image processing and analysis, first of all to the gray image binarization, binarization image.
In practical application, a lot of image analysis is eventually transformed into binary image analysis, such as medical image analysis, foreground detection, character recognition, shape recognition. Binarization + mathematical morphology can solve many problems of object extraction in computer recognition engineering.
Open operation demonstration — text separation and cutting
The opening operation is the process of corrosion and expansion. Used to eliminate small objects, separate objects at slender points, and smooth the boundaries of larger objects without significantly changing their area.
The counterpart of the open operation is the closed operation. In addition, corrosion and expansion are described below.
In CV4J, we encapsulate the common operations of morphology, such as open and close operations, corrosion, and bloat.
Where, the code of open operation is as follows:
public class MorphOpen {
/**
* in order to remove litter noise block, erode + dilate operator
*
* @param binary
* @param structureElement
*/
public void process(ByteProcessor binary, Size structureElement) {
Erode erode = new Erode();
Dilate dilate = newDilate(); erode.process(binary, structureElement); dilate.process(binary, structureElement); }}Copy the code
Let’s start with a full demo
Step 3 If you can’t see clearly, let’s take a look at the enlarged renderings
As you can see in the image above, the demo has finished cutting the text. Let’s see how the code works.
Preparation show the original picture
Resources res = getResources();
final Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.test_binary1);
image0.setImageBitmap(bitmap);Copy the code
The first step is binarization
CV4JImage cv4JImage = new CV4JImage(bitmap);
Threshold threshold = newThreshold(); threshold.process((ByteProcessor)(cv4JImage.convert2Gray().getProcessor()),Threshold.THRESH_TRIANGLE,Threshold.METHOD_TH RESH_BINARY_INV,255);
image1.setImageBitmap(cv4JImage.getProcessor().getImage().toBitmap());Copy the code
The second step is to start operation
MorphOpen morphOpen = new MorphOpen();
cv4JImage.resetBitmap();
morphOpen.process((ByteProcessor)cv4JImage.getProcessor(),new Size(5));
image2.setImageBitmap(cv4JImage.getProcessor().getImage().toBitmap());Copy the code
The third step connects the component tag
ConnectedAreaLabel connectedAreaLabel = new ConnectedAreaLabel();
byte[] mask = new byte[cv4JImage.getProcessor().getWidth() * cv4JImage.getProcessor().getHeight()];
List<Rect> rectangles = new ArrayList<>();
connectedAreaLabel.process((ByteProcessor)cv4JImage.getProcessor(),mask,rectangles,true);
cv4JImage.resetBitmap();
Bitmap newBitmap = cv4JImage.getProcessor().getImage().toBitmap();
if (Preconditions.isNotBlank(rectangles)) {
Tools.drawRects(newBitmap,rectangles);
}
image3.setImageBitmap(newBitmap);Copy the code
In fact, after the third step and the COMBINATION of OCR can recognize the specific text. If combined with the web crawler, the meaning is even greater.
Although CV4J is currently only a mobile library, it was developed in Java and can be easily adapted for desktop.
Corrosion operation demonstration — coin counting
Corrosion operation is a process of eliminating boundary points and making the boundary shrink inward. Can be used to eliminate small and meaningless objects. The corrosion operation scans each pixel of the image and does an “and” operation with the structural element and its overlaid binary image: if both are 1, the pixel of the resulting image is 1, otherwise it is 0.
The opposite of the corrosion operation is the expansion operation. Etch is used to divide individual image elements, while bloat is used to join adjacent elements.
Corrosion algorithm:
It can be simplified as:
So let’s take an example, where we have a bunch of coins in the original drawing, and we do a step-by-step analysis to figure out how many coins there are.
Preparation show the original picture
Resources res = getResources();
final Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.test_coins);
image0.setImageBitmap(bitmap);Copy the code
The first step is binarization
CV4JImage cv4JImage = new CV4JImage(bitmap);
Threshold threshold = newThreshold(); threshold.process((ByteProcessor)(cv4JImage.convert2Gray().getProcessor()),Threshold.THRESH_OTSU,Threshold.METHOD_THRESH _BINARY_INV,255);
image1.setImageBitmap(cv4JImage.getProcessor().getImage().toBitmap());Copy the code
The second step is corrosion operation
Erode erode = new Erode();
cv4JImage.resetBitmap();
erode.process((ByteProcessor)cv4JImage.getProcessor(),new Size(3),10);
image2.setImageBitmap(cv4JImage.getProcessor().getImage().toBitmap());Copy the code
The third step connects the component tag
ConnectedAreaLabel connectedAreaLabel = new ConnectedAreaLabel();
byte[] mask = new byte[cv4JImage.getProcessor().getWidth() * cv4JImage.getProcessor().getHeight()];
int num = connectedAreaLabel.process((ByteProcessor)cv4JImage.getProcessor(),mask,null.false); // Get the number of connected components
SparseIntArray colors = new SparseIntArray();
Random random = new Random();
int height = cv4JImage.getProcessor().getHeight();
int width = cv4JImage.getProcessor().getWidth();
int size = height * width;
for (int i = 0; i<size; i++) {int c = mask[i] & 0xff;
colors.put(c,Color.argb(255, random.nextInt(255),random.nextInt(255),random.nextInt(255)));
}
cv4JImage.resetBitmap();
Bitmap newBitmap = cv4JImage.getProcessor().getImage().toBitmap();
for(int row=0; row<height; row++) {
for (int col = 0; col < width; col++) {
int c = mask[row*width+col] & 0xff;
if (c>0) {
newBitmap.setPixel(col,row,colors.get(c));
}
}
}
image3.setImageBitmap(newBitmap);
if (num>0)
numTextView.setText(String.format("A total of % D coins were identified.",num));Copy the code
Finally, the number of connected components is obtained, that is, the number of coins, and the identified coins are randomly colored.
Cv4j is an image processing library hyperyfish and I developed together, with a pure Java implementation, which is still in its early version. This week, we started to do analysis of binary images (corrosion, expansion, open and close operation, contour extraction, etc.). This module has not completed all functions, and it is expected to be completed next week.
Previous article: Java implements Gaussian blur and spatial convolution of images Java implements advanced gameplay of image filters Java implements image filter effects