Android image processing software and android Image Processing
I have been in the Machine Vision lab for a year and a half, but I am "willful ". I have been learning the content by myself. I still insist that there is no best and simplest technology, only the technology I like. However, I still feel ashamed to say that I often hear my teacher talk about various image processing algorithms, but I can't know the machine vision knowledge until the software was born. My research is mainly about the Android system, from the upper layer to the lower layer. I have always wanted to contact my supervisor and the lab topic, so that I can communicate with the lab cool people more often ~ Therefore, I learned a little about image processing technology and developed an image processing tool for the Android platform, it helps users quickly preview the results of the images to be processed under different algorithms in real time. Because I have learned too few algorithms, I will gradually add them to the software after I have learned more in the future and expand the software functions.
First, let's talk about the functions that can be implemented by the software so far:
* Enable camera preview for mobile phones
* Convert the collected image into a grayscale image for preview
* Preview the grayscale image after being converted to Sobel
* Binarization the image after Sobel
* The segmentation threshold can be dynamically adjusted at any time during binarization.
* You can use the photo button to lock the image and perform Edge Extraction once.
The software is as follows:
First, open the main interface that the software sees:
Click the menu to switch to the grayscale image:
Switch to Sobel Transformation
Binary segmentation with a threshold of 50
Finally, perform edge extraction:
Four algorithms are involved. You can find the specific Algorithm Implementation in the software source code. Click to download the source code.
The entire software has three classes, that is, three different functional parts, among which MainActivity. java is the main class. The following describes the entire software architecture based on three different functional components:
1. Main Interface
MainActivity. java:
The first is the interface layout. An ImageView is used to display the entire preview box. In addition, a photo button and a menu button are added. Click the menu button to bring up the menu. Finally, if the current request is a binarization algorithm, a sliding progress bar and a text input box are displayed to dynamically adjust the threshold. The Code is as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ImageView android:id="@+id/preview" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/takePic_bt" android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:background="@drawable/shutter" android:onClick="onClick_takePic" /> <ListView android:id="@+id/list_view" android:layout_width="150dp" android:layout_height="match_parent" android:layout_marginTop="20dp" android:divider="#ff555555" android:dividerHeight="1.3dp" android:listSelector="@android:color/holo_blue_bright" android:visibility="gone" > </ListView> <Button android:id="@+id/takePic_bt" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="15dp" android:layout_marginLeft="5dp" android:background="@drawable/menu" android:onClick="onClick_menu" /> <EditText android:id="@+id/input_threshold" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="20dp" android:inputType="numberDecimal" android:text="240" android:textColor="@android:color/holo_blue_bright" android:visibility="gone" /> <SeekBar android:id="@+id/seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:layout_marginLeft="50dp" android:layout_toLeftOf="@id/input_threshold" android:max="255" android:progress="240" android:visibility="gone" /> <View android:id="@+id/topline" android:layout_width="match_parent" android:layout_height="2dp" android:layout_marginLeft="100dp" android:layout_marginRight="100dp" android:layout_marginTop="50dp" android:background="#444" /> <View android:layout_width="2dp" android:layout_height="180dp" android:layout_alignEnd="@id/topline" android:layout_below="@id/topline" android:background="#444" /> <View android:layout_width="2dp" android:layout_height="180dp" android:layout_alignStart="@id/topline" android:layout_below="@id/topline" android:background="#444" /></RelativeLayout>
The following describes how to listen to menu and photo button events:
Public void onClick_menu (View view) {if (isMenuVisible) {listView. startAnimation (menuInvisible); listView. setVisibility (View. GONE); isMenuVisible = false;} else {listView. startAnimation (menuVisible); listView. setVisibility (View. VISIBLE); isMenuVisible = true;} public void onClick_takePic (View view) throws IOException {getScreen. takePic (); // camera photo}
I added a opacity animation to show the menu to soften the software interface. Transparency compensation animation is relatively simple. Add two animation resources in the res/anim/directory to display and disappear, and then click the event to play the animation.
Next, write click events for the pop-up menu. Here I use the menu made by ListView and set the callback method using the listView. setOnItemClickListener () method. The Code is as follows:
ListView. setOnItemClickListener (new OnItemClickListener () {@ Override public void onItemClick (AdapterView <?> Parent, View view, int position, long id) {if (position = 3) // The grayscale chart opens the progress bar {seekbar. setVisibility (View. VISIBLE); inputThreshold. setVisibility (View. VISIBLE);} else {seekbar. setVisibility (View. GONE); inputThreshold. setVisibility (View. GONE) ;}whichtodisplay = position; // switching algorithm }});
There are two main functions: 1. Enable and disable the threshold progress bar; 2. Switch the user-clicked algorithm. After the progress bar is opened, you must have a listener. Here, you need to listen to the seekBar and editText controls at the same time, and you need to keep them synchronized. The content is easy to understand, as shown below:
// Process SeekBar seekbar. setOnSeekBarChangeListener (new OnSeekBarChangeListener () {@ Override public void onStopTrackingTouch (SeekBar arg0) {thresholdValue = arg0.getProgress ()> 255? 255: arg0. getProgress () ;}@ Override public void onStartTrackingTouch (SeekBar arg0) {}@ Override public void onProgressChanged (SeekBar arg0, int arg1, boolean arg2) {inputThreshold. setText (arg0.getProgress () + "") ;}}); // process EditText inputThreshold. setoneditexceptionlistener (new oneditexceptionlistener () {@ Override public boolean oneditexception (TextView v, int actionId, KeyEvent event) {seekbar. setProgress (Integer. parseInt (inputThreshold. getText (). toString (); return false ;}});
Now, basically everything on the main interface is taken into account. below is the image acquisition part.
2. Get the camera image and display the preview
GetScreen. java:
This part mainly applies to the use of Android cameras and previews.
1. Use of the camera:
According to my personal use of the camera, there are 6 simple steps:
① Open the Camera -- Camera. open ();
② Set the Camera parameter -- Camera. getParameters ();
③ Set the image preview container -- Camera. setPreviewTexture ();
④ Start previewing -- Camera. startPreview ();
⑤ Set the preview callback interface -- Camera. setPreviewCallback ();
6. close the Camera -- Camera. close ();
The whole process is actually very simple. The official documents emphasize several errors: one is that the sequence of steps 3 and 4 cannot be reversed, and the other is that the camera must be closed when used up, otherwise, other programs cannot start the camera. After my own test, if you do not close the camera, an exception will also be thrown when you exit, so pay attention to it!
Another thing to note is that the image passed in the setPreviewCallback () method through callback is in the YuV420p format and needs to be converted to the rgb format for processing. Here we use a decodeYUV420SP algorithm. For details, see the source code. After converting to RGB format, you can easily generate Bitmap images and display them on ImageView.
In fact, this part of the more troublesome is the focus step. First, we use the formula for calculating the brightness:
Bright = 0.299 * r + 0.587 * g + 0.114 * B;
Calculate the average brightness of the entire image every ms, and then compare it with the previous value. If the image is in a certain range, it indicates that the front-end image of the camera has stabilized. At this time, focus is performed, set a flag to ensure that focus is not performed before the next stable image appears. The focus function is as follows:
private void autoFocus() { long currentTime = 0, stableTime = 0; currentTime = System.currentTimeMillis(); bright = Pictures.getLight(rgb); if (Math.abs(bright - lastBright) > focusThreshold) { lastBright = bright; hasFocus = false; stableTime = currentTime; } else { if (!hasFocus && currentTime - stableTime >= 500) { camera.autoFocus(new AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { } }); hasFocus = true; } } }
3. Image Algorithms
Pictures. java:
The image processing algorithm is actually involved here. There are several simple algorithms involved here. The principle of the algorithm is not mentioned here. There are many explanations on the Image Processing Technology on the Internet.
The software mainly has the following static methods of algorithms:
* Convert YuV420p to the RGB format: decodeYUV420SP ();
* Calculate the average brightness of an image: getLight ();
* Get an array of eight gray images: getLightArray ();
* Convert a color image to a grayscale image: convertToGrey ();
* Sobel Transformation: sobel ();
* Binarization: turnTo2 ();
* Edge extraction: findFrame ();
Here, I write every algorithm as a static method, which can easily process images using algorithms in other codes, image processing is carried out in the onPreviewFrame () function of the camera preview callback function of GetScreen. This is also the core step of the entire software. The Code is as follows:
@ Override public void onPreviewFrame (byte [] data, Camera camera) {rgb = new int [Pictures. PIC_LENGTH]; sobelPic = new int [Pictures. PIC_LENGTH]; gray = new int [Pictures. PIC_LENGTH]; Pictures. decodeYUV420SP (rgb, data, width, height); switch (MainActivity. whichToDisplay) {case 1: // displays the grayscale image Pictures. convertToGrey (rgb, gray); display = gray; break; case 2: Pictures. convertToGrey (rgb, gray); // Pictures is displayed after sobel transformation. sobel (gray, width, height, sobelPic); display = sobelPic; break; case 3: // binary display Pictures. convertToGrey (rgb, gray); Pictures. sobel (gray, width, height, sobelPic); Pictures. turnTo2 (sobelPic); display = sobelPic; break; default: display = rgb;} bitmap = Bitmap. createBitmap (display, width, height, Config. RGB_565); MainActivity. setImageView (bitmap); autoFocus ();}
First, convert the image to the RGB format (for easy processing). Then, switch to different algorithms based on the menu options on the main interface, and display the images under different algorithms to the ImageView, focus at last.
During image processing, simulation is performed in MATLAB or Visual Stuio. This requires constantly importing images → compiling → final output. With this Android image processing tool, you can observe the results of various images in different algorithms in real time, which is more convenient than that. There are only a few algorithms currently supported. In the future, we will continue to learn some common algorithms and add them to the software. I will also update my blog and share it with you.
If you have any comments or questions, you can leave a message to discuss them at any time ~
APK: http://yun.baidu.com/share/link? Consumer id = 515722756 & uk = 67973003
GitHub Source Code address: https://github.com/hust-MC/Find_Different.git