Simple automatic intelligent object recognition program (machine vision + digital image processing)

Very good machine vision program for object recognition. Attached complete documentation and code. The code is written by matlab with test pictures attached. The picture contains various objects. Through the knowledge of digital image processing, various objects in the picture are automatically recognized.

File: n459.com/f/25127180-479732884-67aeb3 (Access password: 551685)

The following are irrelevant:

-------------------------------------------Dividing line----- ----------------------------------------

01 Overview of sorting algorithm The
so-called sorting algorithm is to re-sort one or more sets of data according to a certain pattern through a specific algorithm factor.

This new sequence follows certain rules and reflects certain laws. Therefore, the processed data is convenient for screening and calculation, which greatly improves the calculation efficiency.

02 Classification of sorting algorithm
Insert picture description here

03 Evaluation Criteria
(1) Time complexity: the measurement of the time spent in the process from the initial state of the sequence to the transformation and shifting of the sorting algorithm to the final sorted result state.

(2) Space complexity: It is the space overhead spent from the initial state of the sequence through the sequence shift transformation process to the final state.

(3) Stability: Stability is a problem that must be considered regardless of time and space, and it is often a very important factor affecting choice.

04 Implementation steps and code
Bubble Sort (Bubble Sort)
is a simple and intuitive sorting algorithm. It repeatedly visited the sequence to be sorted, compared two elements at a time, and exchanged them if they were in the wrong order. The work of visiting the sequence is repeated until there is no more data to be exchanged, which means that the sequence has been sorted. The origin of the name of this algorithm is because the smaller the element will slowly "float" to the top of the sequence through exchange.

(1) Algorithm steps

Step 1: Compare adjacent elements. If the first one is greater than the second, swap the two;
Step 2: Do the same work for each pair of adjacent elements, from the first pair to the last pair at the end. After this step is completed, the last element will be the largest number;
Step 3: Repeat the above steps for all elements, except for the last one;
Step 4: Repeat steps 1 to 3 until the sorting is completed;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class BubbleSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    for (int i = 1; i < arr.length; i++) {
        // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
        boolean flag = true;

        for (int j = 0; j < arr.length - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;

                flag = false;
            }
        }

        if (flag) {
            break;
        }
    }
    return arr;
}

}

Selection Sort (Selection Sort)
is a simple and intuitive sorting algorithm, no matter what data enters it is O(n²) time complexity. So when using it, the smaller the data size, the better.

(1) Algorithm steps

Step 1: First find the smallest (large) element in the unsorted sequence and store it at the beginning of the sorted sequence;
Step 2: Continue to find the smallest (large) element from the remaining unsorted elements, and then place it in the sorted sequence At the end;
Step 3: Repeat step 2 until all elements are sorted;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class SelectionSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    // 总共要经过 N-1 轮比较
    for (int i = 0; i < arr.length - 1; i++) {
        int min = i;

        // 每轮需要比较的次数 N-i
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[min]) {
                // 记录目前能找到的最小值元素的下标
                min = j;
            }
        }

        // 将找到的最小值和i位置所在的值进行交换
        if (i != min) {
            int tmp = arr[i];
            arr[i] = arr[min];
            arr[min] = tmp;
        }

    }
    return arr;
}

}

Insertion Sort (Insertion Sort)
The algorithm description of insertion sort is a simple and intuitive sorting algorithm. Its working principle is to construct an ordered sequence. For unsorted data, scan from back to front in the sorted sequence, find the corresponding position and insert. In the implementation of insertion sort, in-place sorting is usually used (that is, sorting that only needs O(1) extra space), so in the process of scanning from back to forward, it is necessary to repeatedly shift the sorted elements back gradually , To provide insertion space for the latest elements.

(1) Algorithm steps

Step 1: Starting from the first element, the element can be considered to have been sorted;
Step 2: Take out the next element and scan from back to forward in the sequence of sorted elements;
Step 3: If the element (sorted) is greater than New element, move the element to the next position;
Step 4: Repeat step 3 until you find the position where the sorted element is less than or equal to the new element;
Step 5: Insert the new element into the position;
Step 6: Repeat the step 2~5;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class InsertSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
    for (int i = 1; i < arr.length; i++) {

        // 记录要插入的数据
        int tmp = arr[i];

        // 从已经排序的序列最右边的开始比较,找到比其小的数
        int j = i;
        while (j > 0 && tmp < arr[j - 1]) {
            arr[j] = arr[j - 1];
            j--;
        }

        // 存在比其小的数,插入
        if (j != i) {
            arr[j] = tmp;
        }

    }
    return arr;
}

}

Hill sort (Shell Sort)
Hill sort, also known as decreasing incremental sort algorithm, is a more efficient and improved version of insertion sort. But Hill sorting is an unstable sorting algorithm.

Hill sorting proposes an improved method based on the following two properties of insertion sort:

When data insertion sort operation almost sorted, high efficiency, i.e., efficiency of the linear ordering can be achieved;
however insertion sort is generally inefficient because the data insertion sort can only move one;
Xi The basic idea of ​​Erre sorting is: first divide the entire sequence of records to be sorted into several sub-sequences for direct insertion sorting, and when the records in the whole sequence are "basically ordered", then perform direct insertion sorting for all records in sequence.

(1) Algorithm steps

Step 1: Select an incremental sequence t1, t2,..., tk, where ti> tj, tk = 1;
Step 2: Sort the sequence by k times according to the number of incremental sequences k;
Step 3: Sort each pass , According to the corresponding increment ti, divide the sequence to be sorted into several sub-sequences of length m, and perform direct insertion sort on each sub-table respectively. When only the increment factor is 1, the entire sequence is treated as a table, and the length of the table is the length of the entire sequence;

(2) Process demonstration

Insert picture description here

(3) Code implementation

public class ShellSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    int gap = 1;
    while (gap < arr.length) {
        gap = gap * 3 + 1;
    }

    while (gap > 0) {
        for (int i = gap; i < arr.length; i++) {
            int tmp = arr[i];
            int j = i - gap;
            while (j >= 0 && arr[j] > tmp) {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = tmp;
        }
        gap = (int) Math.floor(gap / 3);
    }

    return arr;
}

}
Merge Sort (Merge Sort) Merge Sort
is an effective sorting algorithm based on merge operations. This algorithm is a very typical application of Divide and Conquer. Merge sort is a stable sorting method. Combine existing ordered subsequences to obtain a completely ordered sequence; that is, first make each subsequence in order, and then make the subsequences in order. If two ordered lists are merged into one ordered list, it is called 2-way merge.

Like selection sort, the performance of merge sort is not affected by the input data, but it performs much better than selection sort, because it is always O(n log n) time complexity. The price is the need for additional memory space.

(1) Algorithm steps

Step 1: Divide the input sequence of length n into two subsequences of length n/2;
Step 2: Use merge sorting on these two subsequences respectively;
Step 3: Combine the two sorted subsequences into one final The sorting sequence;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class MergeSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    if (arr.length < 2) {
        return arr;
    }
    int middle = (int) Math.floor(arr.length / 2);

    int[] left = Arrays.copyOfRange(arr, 0, middle);
    int[] right = Arrays.copyOfRange(arr, middle, arr.length);

    return merge(sort(left), sort(right));
}

protected int[] merge(int[] left, int[] right) {
    int[] result = new int[left.length + right.length];
    int i = 0;
    while (left.length > 0 && right.length > 0) {
        if (left[0] <= right[0]) {
            result[i++] = left[0];
            left = Arrays.copyOfRange(left, 1, left.length);
        } else {
            result[i++] = right[0];
            right = Arrays.copyOfRange(right, 1, right.length);
        }
    }

    while (left.length > 0) {
        result[i++] = left[0];
        left = Arrays.copyOfRange(left, 1, left.length);
    }

    while (right.length > 0) {
        result[i++] = right[0];
        right = Arrays.copyOfRange(right, 1, right.length);
    }

    return result;
}

}

Quick Sort (Quick Sort)
Quick Sort is a sorting algorithm developed by Tony Hall. On average, it takes Ο(n log n) comparisons to sort n items. In the worst case, Ο(n^2) comparisons are required, but this situation is not common. In fact, quicksort is usually significantly faster than other Ο(nlogn) algorithms because its inner loop can be implemented efficiently on most architectures.

Quick sort uses a divide and conquer (Divide and conquer) strategy to divide a list into two sub-lists.

(1) Algorithm steps

Step 1: Pick out an element from the sequence, which is called a "pivot";
Step 2: Reorder the sequence, place all elements smaller than the benchmark value in front of the benchmark, and place all elements larger than the benchmark value on the benchmark (The same number can go to either side). After the partition exits, the benchmark is in the middle of the sequence. This is called a partition operation;
Step 3: Recursively sort the sub-sequences of elements smaller than the reference value and the sub-sequences of elements larger than the reference value;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class QuickSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    return quickSort(arr, 0, arr.length - 1);
}

private int[] quickSort(int[] arr, int left, int right) {
    if (left < right) {
        int partitionIndex = partition(arr, left, right);
        quickSort(arr, left, partitionIndex - 1);
        quickSort(arr, partitionIndex + 1, right);
    }
    return arr;
}

private int partition(int[] arr, int left, int right) {
    // 设定基准值(pivot)
    int pivot = left;
    int index = pivot + 1;
    for (int i = index; i <= right; i++) {
        if (arr[i] < arr[pivot]) {
            swap(arr, i, index);
            index++;
        }
    }
    swap(arr, pivot, index - 1);
    return index - 1;
}

private void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

}
Heap Sort (Heap Sort)
Heap Sort refers to a sorting algorithm designed using the data structure of the heap. Stacking is a structure that approximates a complete binary tree, and at the same time satisfies the nature of stacking: that is, the key or index of the child node is always less than (or greater than) its parent node. Heap sorting can be said to be a selective sort that uses the concept of a heap to sort. There are two methods:

Large top heap: The value of each node is greater than or equal to the value of its child nodes, and is used in ascending order in the heap sorting algorithm;
small top heap: The value of each node is less than or equal to the value of its child nodes, in the heap Sorting algorithm is used in descending order;
the average time complexity of heap sorting is O(n log n).

(1) Algorithm steps

Step 1: Construct the initial key sequence to be sorted (R1, R2...Rn) into a large top pile, which is the initial disordered area;
Step 2: Combine the top element R[1] with the last element R[ n] exchange, at this time a new disordered area (R1, R2,...Rn-1) and a new ordered area (Rn) are obtained, and R[1,2...n-1]<=R[n ];
Step 3: Since the new top of the heap R[1] after the exchange may violate the nature of the heap, the current disordered area (R1, R2,...Rn-1) needs to be adjusted to a new heap, and then R[ 1] Exchange with the last element of the disordered region to obtain a new disordered region (R1, R2...Rn-2) and a new ordered region (Rn-1, Rn). Repeat this process until the number of elements in the ordered area is n-1, then the entire sorting process is completed;

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class HeapSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    int len = arr.length;

    buildMaxHeap(arr, len);

    for (int i = len - 1; i > 0; i--) {
        swap(arr, 0, i);
        len--;
        heapify(arr, 0, len);
    }
    return arr;
}

private void buildMaxHeap(int[] arr, int len) {
    for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
        heapify(arr, i, len);
    }
}

private void heapify(int[] arr, int i, int len) {
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    int largest = i;

    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }

    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }

    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest, len);
    }
}

private void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

}

Counting Sort (Counting Sort)
The core of counting sort is to convert input data values ​​into keys and store them in an additional array space. As a sort of linear time complexity, the count sort requires that the input data must be an integer with a certain range.

Count sorting is a stable sorting algorithm. Counting sorting uses an additional array C, where the i-th element is the number of elements in the array A to be sorted whose value is equal to i. Then according to the array C to arrange the elements in A to the correct position. It can only sort integers.

(1) Algorithm steps

Step 1: Find the largest and smallest elements in the array to be sorted;
Step 2: Count the number of occurrences of each element with the value i in the array and store it in the i-th item of the array C;
Step 3: Accumulate all the counts (Starting from the first element in C, each item is added to the previous item);
Step 4: Reverse filling the target array: Put each element i in the C(i)th item of the new array, every time One element will subtract 1 from C(i);

(2) Process demonstration,
insert picture description here

(3) Code implementation

public class CountingSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
    // 对 arr 进行拷贝,不改变参数内容
    int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

    int maxValue = getMaxValue(arr);

    return countingSort(arr, maxValue);
}

private int[] countingSort(int[] arr, int maxValue) {
    int bucketLen = maxValue + 1;
    int[] bucket = new int[bucketLen];

    for (int value : arr) {
        bucket[value]++;
    }

    int sortedIndex = 0;
    for (int j = 0; j < bucketLen; j++) {
        while (bucket[j] > 0) {
            arr[sortedIndex++] = j;
            bucket[j]--;
        }
    }
    return arr;
}

private int getMaxValue(int[] arr) {
    int maxValue = arr[0];
    for (int value : arr) {
        if (maxValue < value) {
            maxValue = value;
        }
    }
    return maxValue;
}

}

Bucket Sort
is an upgraded version of counting sort. It uses the mapping relationship of functions, and the key to efficiency lies in the determination of the mapping function. In order to make bucket sorting more efficient, we need to do two things:

In the case of sufficient extra space, try to increase the number of buckets.
The mapping function used can evenly distribute the input N data into K buckets.
At the same time, for the sorting of the elements in the buckets, which comparison sorting algorithm is selected for performance The impact is crucial.

(1) Algorithm steps

Step 1: Artificially set a BucketSize as how many different values ​​can be placed in each bucket (for example, when BucketSize==5, the bucket can store {1,2,3,4,5} these types of numbers, but the capacity Unlimited, that can store 100 3);
Step 2: Traverse the input data, and put the data one by one into the corresponding bucket;
Step 3: Sort each bucket that is not empty, you can use other sorting methods, You can also use bucket sorting recursively;
Step 4: Splice the sorted data from the bucket that is not empty;

Note that if you use bucket sorting to sort each bucket recursively, when the number of buckets is 1, you must manually reduce the BucketSize to increase the number of buckets in the next cycle, otherwise it will fall into an infinite loop and cause memory overflow;

(2) Process demonstration,
insert picture description here

(3) Code implementation

/**
* 桶排序
*
* @param array
* @param bucketSize
* @return
*/
public static ArrayList BucketSort(ArrayList array, int bucketSize) {
if (array == null || array.size() < 2)
return array;
int max = array.get(0), min = array.get(0);
// 找到最大值最小值
for (int i = 0; i < array.size(); i++) {
if (array.get(i) > max)
max = array.get(i);
if (array.get(i) < min)
min = array.get(i);
}
int bucketCount = (max - min) / bucketSize + 1;
ArrayList<ArrayList> bucketArr = new ArrayList<>(bucketCount);
ArrayList resultArr = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketArr.add(new ArrayList());
}
for (int i = 0; i < array.size(); i++) {
bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
}
for (int i = 0; i < bucketCount; i++) {
if (bucketSize == 1) { // 如果待排序数组中有重复数字时
for (int j = 0; j < bucketArr.get(i).size(); j++)
resultArr.add(bucketArr.get(i).get(j));
} else {
if (bucketCount == 1)
bucketSize–;
ArrayList temp = BucketSort(bucketArr.get(i), bucketSize);
for (int j = 0; j < temp.size(); j++)
resultArr.add(temp.get(j));
}
}
return resultArr;
}

Radix Sort (Radix Sort)
is also a non-comparative sorting algorithm, sorting each bit, starting from the lowest bit, the complexity is O(kn), which is the length of the array, and k is the largest bit of the number in the array number;

Cardinality sorting is to sort according to the low order first, then collect; then sort according to the high order, then collect; and so on, until the highest order. Sometimes some attributes have a priority order, first sort by low priority, and then sort by high priority. The final order is that the high priority is first, and the low priority with the same high priority is first. Cardinality sorting is based on sorting separately and collecting separately, so it is stable.

(1) Algorithm steps

Step 1: Get the maximum number in the array and get the number of digits;
Step 2: arr is the original array, and each bit is taken from the lowest bit to form the radix array;
Step 3: Count and sort the radix (using counting sorting is suitable for small The characteristics of the range number);

(2) Process demonstration,
insert picture description here

(3) Code implementation

/**

  • Radix Sort
    */
    public class RadixSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception { // Copy arr without changing the parameter content int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

     int maxDigit = getMaxDigit(arr);
     return radixSort(arr, maxDigit);
    

    }

    /**

    • Get the highest digit
      */
      private int getMaxDigit(int[] arr) { int maxValue = getMaxValue(arr); return getNumLenght(maxValue); }


    private int getMaxValue(int[] arr) {
    int maxValue = arr[0];
    for (int value : arr) {
    if (maxValue < value) {
    maxValue = value;
    }
    }
    return maxValue;
    }

    protected int getNumLenght(long num) {
    if (num == 0) {
    return 1;
    }
    int lenght = 0;
    for (long temp = num; temp != 0; temp /= 10) {
    lenght++;
    }
    return lenght;
    }

    private int[] radixSort(int[] arr, int maxDigit) {
    int mod = 10;
    int dev = 1;

     for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
         // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
         int[][] counter = new int[mod * 2][0];
    
         for (int j = 0; j < arr.length; j++) {
             int bucket = ((arr[j] % mod) / dev) + mod;
             counter[bucket] = arrayAppend(counter[bucket], arr[j]);
         }
    
         int pos = 0;
         for (int[] bucket : counter) {
             for (int value : bucket) {
                 arr[pos++] = value;
             }
         }
     }
    
     return arr;
    

    }

    /**

    • Automatically expand capacity and save data
    • @param arr
    • @param value
      */
      private int[] arrayAppend(int[] arr, int value) {
      arr = Arrays.copyOf(arr, arr.length + 1);
      arr[arr.length - 1] = value;
      return arr;
      }
      }

05 Summary
Insert picture description here

Guess you like

Origin blog.csdn.net/gumenghua_com1/article/details/112860022