- IPS200 display menu with real-time status and parameter settings - Camera image processing and line tracking - IMU attitude solution and PID control - WiFi SPI oscilloscope data transmission
111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
#include "user_image_process.h"
|
|
|
|
IFX_ALIGN(4) uint8 image_binary_1[MT9V03X_1_H][MT9V03X_1_W];
|
|
|
|
int user_otsu_threshold(uint8 *image, uint16 col, uint16 row)
|
|
{
|
|
#define GRAYSCALE 256
|
|
uint16 width = col;
|
|
uint16 height = row;
|
|
int pixelCount[GRAYSCALE];
|
|
float pixelPro[GRAYSCALE];
|
|
int i, j;
|
|
int pixelSum = width * height / 4;
|
|
int threshold = 0;
|
|
uint8 *data = image;
|
|
|
|
for (i = 0; i < GRAYSCALE; i++)
|
|
{
|
|
pixelCount[i] = 0;
|
|
pixelPro[i] = 0;
|
|
}
|
|
|
|
uint32 gray_sum = 0;
|
|
for (i = 0; i < height; i += 2)
|
|
{
|
|
for (j = 0; j < width; j += 2)
|
|
{
|
|
pixelCount[(int)data[i * width + j]]++;
|
|
gray_sum += (int)data[i * width + j];
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < GRAYSCALE; i++)
|
|
{
|
|
pixelPro[i] = (float)pixelCount[i] / pixelSum;
|
|
}
|
|
|
|
float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
|
|
w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
|
|
|
|
for (j = 0; j < GRAYSCALE; j++)
|
|
{
|
|
w0 += pixelPro[j];
|
|
u0tmp += j * pixelPro[j];
|
|
w1 = 1 - w0;
|
|
|
|
/* 防止除零: 某一类为空时跳过该阈值 */
|
|
if (w0 < 1e-6f || w1 < 1e-6f)
|
|
continue;
|
|
|
|
u1tmp = (float)gray_sum / pixelSum - u0tmp;
|
|
|
|
u0 = u0tmp / w0;
|
|
u1 = u1tmp / w1;
|
|
u = u0tmp + u1tmp;
|
|
|
|
deltaTmp = w0 * (u0 - u) * (u0 - u) + w1 * (u1 - u) * (u1 - u);
|
|
|
|
if (deltaTmp > deltaMax)
|
|
{
|
|
deltaMax = deltaTmp;
|
|
threshold = j;
|
|
}
|
|
}
|
|
|
|
return threshold;
|
|
}
|
|
|
|
void user_image_binarize(uint8 *src_image, uint8 (*dst_image)[MT9V03X_1_W], uint16 col, uint16 row, int threshold)
|
|
{
|
|
uint16 i, j;
|
|
|
|
for (i = 0; i < row; i++)
|
|
{
|
|
for (j = 0; j < col; j++)
|
|
{
|
|
dst_image[i][j] = (src_image[i * col + j] >= (uint8)threshold) ? IMG_WHITE : IMG_BLACK;
|
|
}
|
|
}
|
|
}
|
|
|
|
void user_image_denoise(uint8 (*image)[MT9V03X_1_W], uint16 col, uint16 row)
|
|
{
|
|
uint16 i, j;
|
|
static uint8 buf[MT9V03X_1_H][MT9V03X_1_W];
|
|
|
|
for (i = 0; i < row; i++) {
|
|
for (j = 0; j < col; j++) {
|
|
buf[i][j] = image[i][j];
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < row - 1; i++) {
|
|
for (j = 1; j < col - 1; j++) {
|
|
int cnt = 0;
|
|
if (buf[i-1][j-1] == IMG_WHITE) cnt++;
|
|
if (buf[i-1][j ] == IMG_WHITE) cnt++;
|
|
if (buf[i-1][j+1] == IMG_WHITE) cnt++;
|
|
if (buf[i ][j-1] == IMG_WHITE) cnt++;
|
|
if (buf[i ][j ] == IMG_WHITE) cnt++;
|
|
if (buf[i ][j+1] == IMG_WHITE) cnt++;
|
|
if (buf[i+1][j-1] == IMG_WHITE) cnt++;
|
|
if (buf[i+1][j ] == IMG_WHITE) cnt++;
|
|
if (buf[i+1][j+1] == IMG_WHITE) cnt++;
|
|
|
|
image[i][j] = (cnt >= 5) ? IMG_WHITE : IMG_BLACK;
|
|
}
|
|
}
|
|
}
|
|
|