You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

5627 lines
207 KiB

#include <opencv2/opencv.hpp>
#include <opencv2/video.hpp>
#include <opencv2/img_hash.hpp>
#include "ivs.hpp"
#include "ivsC.h"
#include "utility.h"
#include <sys/time.h>
#include <iostream>
#include <random>
using namespace cv;
using namespace std;
//Ptr<BackgroundSubtractor> g_pMOG2;
int g_count_mog2 = 0;
//Ptr<BackgroundSubtractor> g_pMOG2_2;
int g_count_mog2_2 = 0;
long last_ms_differ_image_test = 0;
long current_ms_differ_image_test = 0;
Mat img_background_array_test[MAX_TIME_LENGTH_TEST];
int store_img_background_array_length_test = 0;
int current_index_img_background_array_test = 0;
int virtual_index_img_background_array_test = 0;
class MultiLayerMOG2 {
public:
MultiLayerMOG2(int layers, int history) : layers(layers), history(history){
initialize();
}
//~MultiLayerGMM() {
//clearMemory(); // 清空記憶體
//}
void initialize() {
for (int i = 0; i < layers; ++i) {
// 每一層使用不同的 MOG2 背景減除器
Ptr<BackgroundSubtractor> mog2 = createBackgroundSubtractorMOG2(history, 20, false);
mog2Models.push_back(mog2);
}
// 設定每層的濾波器大小
filterSizes = { 5, 3 }; // 濾波器大小
//filterSizes = { 3 }; // 濾波器大小
}
void processFrame(const Mat& frame, Mat& fgMask, double learning_rate) {
double alpha = 0.5;
Mat combinedMask = Mat::zeros(frame.size(), CV_8UC1);
Mat smoothedFrame;
// 在每一層前進行高斯濾波
for (int layer = 0; layer < layers; ++layer) {
// 根據層數選擇相應的濾波器大小
int kernelSize = filterSizes[layer]; // 15, 9, 3
GaussianBlur(frame, smoothedFrame, Size(kernelSize, kernelSize), 0);
Mat layerMask;
// 應用對應層的 MOG2 模型
mog2Models[layer]->apply(smoothedFrame, layerMask, learning_rate);
smoothedFrame.release();
// 將每層的前景掩模合併
Mat temp_combinedMask;
if (layer == 0) {
temp_combinedMask = layerMask.clone();
}
else {
temp_combinedMask = alpha * combinedMask + (1 - alpha) * layerMask;
}
combinedMask.release();
layerMask.release();
combinedMask = temp_combinedMask.clone();
temp_combinedMask.release();
}
fgMask = combinedMask.clone();
combinedMask.release();
}
void clearMemory() {
mog2Models.clear(); // 清空 MOG2 模型列表
filterSizes.clear();
}
private:
int layers; // 層數
int history; // 歷史長度
vector<Ptr<BackgroundSubtractor>> mog2Models; // MOG2 模型列表
vector<int> filterSizes; // 濾波器大小
};
MultiLayerMOG2 g_multiLayerMOG2(2, 500); // 2 層,歷史長度設為 500
MultiLayerMOG2 g_multiLayerMOG2_2(2, 500); // 2 層,歷史長度設為 500
struct IVSHashInfo{
Rect bbox;
time_t firstSeen; // 首次偵測時間
time_t lastSeen; // 最後一次更新的時間
Mat hash_value; //哈希值
};
vector<IVSHashInfo> g_ivs_hash_record;
Mat generateChecksumUsingHash(Mat& image, Rect region) {
Mat roi = image(region);
Mat hashValue;
//Mat binaryImg;
//threshold(roi, binaryImg, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
// 使用 pHash 算法生成哈希
img_hash::pHash(roi, hashValue);
// 只保留哈希值的前兩個位元,並轉換為 16 位元
//unsigned short checksum = hashValue.at<uchar>(0) + (hashValue.at<uchar>(1) << 8);
//binaryImg.release();
roi.release();
return hashValue;
//return checksum;
}
double hammingDistance(Mat& hash1, Mat& hash2) {
Mat diff;
bitwise_xor(hash1, hash2, diff);
// 計算 XOR 結果中非零元素的個數
//int hamming_Distance = countNonZero(diff);
double meanDiff = mean(diff)[0];
diff.release();
return meanDiff;
}
// 比較兩個檢查碼,並允許誤差範圍
int isChecksumSimilar(Mat& hash1, Mat& hash2, double tolerance) {
int ret = 0;
if (hash1.size() == hash2.size() && hash1.type() == hash2.type()) {
double distance = hammingDistance(hash1, hash2);
if (distance <= tolerance) {
ret = 1;
}
}
return ret;
}
void clear_g_ivs_hash_record() {
for (int j = g_ivs_hash_record.size() - 1; j >= 0; --j) { // 從後往前遍歷,避免刪除時影響索引
g_ivs_hash_record[j].hash_value.release();
g_ivs_hash_record.erase(g_ivs_hash_record.begin() + j); // 刪除符合條件的車輛
}
if (g_ivs_hash_record.empty()) {
g_ivs_hash_record.clear(); // 清除所有元素
g_ivs_hash_record.shrink_to_fit(); // 釋放未使用的記憶體
}
}
void push_back_to_record_hash(Rect region, Mat& region_hash_value) {
if (g_ivs_hash_record.size() < MAX_QUEUE_HASH_SIZE)
{
IVSHashInfo newHash;
newHash.bbox.x = region.x;
newHash.bbox.y = region.y;
newHash.bbox.width = region.width;
newHash.bbox.height = region.height;
time_t current_time = time(0);
newHash.firstSeen = current_time;
newHash.lastSeen = current_time;
newHash.hash_value = region_hash_value.clone();
g_ivs_hash_record.push_back(newHash);
}
}
void pop_not_to_record_hash(time_t current_time) {
// 用 for 迴圈檢查車輛是否需要清除
if (g_ivs_hash_record.size() >= 1) {
for (int j = g_ivs_hash_record.size() - 1; j >= 0; --j) { // 從後往前遍歷,避免刪除時影響索引
double unseenDuration = difftime(current_time, g_ivs_hash_record[j].lastSeen);
if (unseenDuration > 10.0)
{
g_ivs_hash_record[j].hash_value.release();
g_ivs_hash_record.erase(g_ivs_hash_record.begin() + j); // 刪除符合條件的車輛
}
else {
unseenDuration = difftime(current_time, g_ivs_hash_record[j].firstSeen);
if (unseenDuration > 70.0)
{
g_ivs_hash_record[j].hash_value.release();
g_ivs_hash_record.erase(g_ivs_hash_record.begin() + j); // 刪除符合條件的車輛
}
}
}
if (g_ivs_hash_record.empty()) {
g_ivs_hash_record.clear(); // 清除所有元素
g_ivs_hash_record.shrink_to_fit(); // 釋放未使用的記憶體
}
}
}
int check_if_ivs_hash_has_been_recorded(Mat& current_ivs_hash) {
int check_if_recorded = 0;
for (int i = 0; i < g_ivs_hash_record.size(); i++) {
if (isChecksumSimilar(current_ivs_hash, g_ivs_hash_record[i].hash_value,3.0)) {
check_if_recorded = 1;
time_t current_time = time(0);
g_ivs_hash_record[i].lastSeen = current_time;
break;
}
}
return check_if_recorded;
}
float g_progress_bar = -1.0;
void set_g_progress_bar(int progress_bar) {
g_progress_bar = (float)progress_bar;
}
int get_g_progress_bar() {
return (int)g_progress_bar;
}
float rect_nms(Rect det1, Rect det2) {
float a1 = det1.width * det1.height;
float a2 = det2.width * det2.height;
float left_nms = det1.x;
float low_nms = det1.y;
float right_nms = det1.x + det1.width;
float high_nms = det1.y + det1.height;
if (det2.x > left_nms)
left_nms = det2.x;
if ((det2.x + det2.width) < right_nms)
right_nms = (det2.x + det2.width);
if (det2.y > low_nms)
low_nms = det2.y;
if ((det2.y + det2.height) < high_nms)
high_nms = det2.y + det2.height;
if (left_nms >= right_nms || low_nms >= high_nms)
return 0.0;
float sa = (right_nms - left_nms) * (high_nms - low_nms);
return sa / (a1 + a2 - sa);
}
float rect_overlap_ratio_union(Rect det1, Rect det2)
{
if (det1.x > det2.x + det2.width) { return 0.0; }
if (det1.y > det2.y + det2.height) { return 0.0; }
if (det1.x + det1.width < det2.x) { return 0.0; }
if (det1.y + det1.height < det2.y) { return 0.0; }
float colInt = abs(std::min(det1.x + det1.width, det2.x + det2.width) - std::max(det1.x, det2.x));
float rowInt = abs(std::min(det1.y + det1.height, det2.y + det2.height) - std::max(det1.y, det2.y));
float overlapArea = colInt * rowInt; //相交處面積
float area1 = det1.width * det1.height;
float area2 = det2.width * det2.height;
//float smallerArea = (area1 > area2) ? area2 : area1;
//return overlapArea / smallerArea; //相交處面積占較小物件比例
return overlapArea / (area1 + area2 - overlapArea); //相交處面積比例占大小物件加總比例
}
float rect_overlap_ratio(Rect det1, Rect det2)
{
if (det1.x > det2.x + det2.width) { return 0.0; }
if (det1.y > det2.y + det2.height) { return 0.0; }
if (det1.x + det1.width < det2.x) { return 0.0; }
if (det1.y + det1.height < det2.y) { return 0.0; }
float colInt = abs(std::min(det1.x + det1.width, det2.x + det2.width) - std::max(det1.x, det2.x));
float rowInt = abs(std::min(det1.y + det1.height, det2.y + det2.height) - std::max(det1.y, det2.y));
float overlapArea = colInt * rowInt; //相交處面積
float area1 = det1.width * det1.height;
float area2 = det2.width * det2.height;
float smallerArea = (area1 > area2) ? area2 : area1;
return overlapArea / smallerArea; //相交處面積占較小物件比例
//return overlapArea / (area1 + area2 - overlapArea); //相交處面積比例占大小物件加總比例
}
void initial_ivs() {
// 初始化 MOG2 背景分割器
//int history = 500; // 記憶歷史幀數
//double varThreshold = 20; // 變異閾值 16
//bool detectShadows = false; // 是否檢測陰影
//g_pMOG2 = createBackgroundSubtractorMOG2(history, varThreshold, detectShadows);
//g_pMOG2_2 = createBackgroundSubtractorMOG2(history, varThreshold, detectShadows);
}
#if defined GY_OS_AMBA || defined GY_OS_NOVA
char color_name[NUM_STRINGS_COLOR][MAX_LENGTH_COLOR] = {
{"White"},
{"Silver"},//test_nnctrl_live.c convert Silver to Gray
{"Darkgray"},
{"Black"},
{"Red"},
{"Yellow"},
{"Green"},
{"Cyan"},
{"Blue"},
{"Purple"},
{"Orange"}
};
//Cyan id設定為0代表 空值
int color_id_array[NUM_STRINGS_COLOR] = {
9,10,11,8,1,3,4,6,5,7,2
};
long last_ms_differ_image = 0;
long current_ms_differ_image = 0;
Mat img_background_short_term;
Mat img_background_long_term;
Mat img_median_short_term;
Mat img_median_long_term;
Mat img_background_short_term_yuv;
Mat img_background_long_term_yuv;
Mat img_background_array[MAX_TIME_LENGTH];
int store_img_background_array_length = 0;
int current_index_img_background_array = 0;
int virtual_index_img_background_array = 0;
int check_if_compute_median_finish = 1;
int check_if_tempering_happened = 0;
int check_if_tempering_many_times = -100;//TEMPERING_MANY_TIMES
//int last_day_or_night_mode = -1; //day : 1 ; night : 2
//int current_day_or_night_mode = -1; //day : 1 ; night : 2
int record_change_state = 0;
int current_store_object_x[MAX_NUM_OBJECT] = { 0 };
int current_store_object_y[MAX_NUM_OBJECT] = { 0 };
int current_store_object_w[MAX_NUM_OBJECT] = { 0 };
int current_store_object_h[MAX_NUM_OBJECT] = { 0 };
int current_store_object_size = 0;
int last_store_object_x[MAX_NUM_OBJECT] = { 0 };
int last_store_object_y[MAX_NUM_OBJECT] = { 0 };
int last_store_object_w[MAX_NUM_OBJECT] = { 0 };
int last_store_object_h[MAX_NUM_OBJECT] = { 0 };
int last_store_object_size = 0;
//int bg_learning_first_to_show = 0;
int tempering_ready = 0;
double single_channel_median(Mat channel,int color_max)
{
double m = (channel.rows*channel.cols) / 2;
int bin = 0;
double med = -1.0;
int histSize = color_max;
float range[] = { 0, (float)color_max };
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
calcHist(&channel, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
for (int i = 0; i < histSize && med < 0.0; ++i)
{
bin += cvRound(hist.at< float >(i));
if (bin > m && med < 0.0)
med = i;
}
return med;
}
Mat compute_median(vector<Mat> vec) {
//struct timeval currtime;
//gettimeofday(&currtime, NULL);
//long now_ms = (currtime.tv_sec * 1000) + (currtime.tv_usec / 1000); //單位為毫秒
//long last_ms = now_ms;
// Note: Expects the image to be CV_8UC3
Mat medianImg(vec[0].rows, vec[0].cols, CV_8UC3, Scalar(0, 0, 0));
//printf("\n-------vec[0].rows:%d\n", vec[0].rows);
//printf("\n-------vec[0].cols:%d\n", vec[0].cols);
int row_size = vec[0].rows;
for (int row = 2; row < row_size; row++) {
for (int col = 0; col < vec[0].cols; col++) {
//if ((row + col) % 3 == 0 || (col % 2 == 0 && row % 3 == 0))
{
int record_element_B[256] = { 0 };
int record_element_G[256] = { 0 };
int record_element_R[256] = { 0 };
for (int imgNumber = 0; imgNumber < (int)vec.size(); imgNumber++) {
int i_B = vec[imgNumber].at<Vec3b>(row, col)[0];
int i_G = vec[imgNumber].at<Vec3b>(row, col)[1];
int i_R = vec[imgNumber].at<Vec3b>(row, col)[2];
i_B = i_B - (i_B % 3);
i_G = i_G - (i_G % 3);
i_R = i_R - (i_R % 3);
record_element_B[i_B]++;
record_element_G[i_G]++;
record_element_R[i_R]++;
}
int i_medianImg_B = -1;
int i_medianImg_G = -1;
int i_medianImg_R = -1;
int current_count_record_B = 0;
int current_count_record_G = 0;
int current_count_record_R = 0;
int last_count_record_B = 0;
int last_count_record_G = 0;
int last_count_record_R = 0;
for (int index_record = 0; index_record < 256; index_record+=3) {
if (record_element_B[index_record] >= 1) {
current_count_record_B += record_element_B[index_record];
if (last_count_record_B < (int)vec.size() / 2 && current_count_record_B >= (int)vec.size() / 2) {
i_medianImg_B = index_record;
}
last_count_record_B = current_count_record_B;
}
if (record_element_G[index_record] >= 1) {
current_count_record_G += record_element_G[index_record];
if (last_count_record_G < (int)vec.size() / 2 && current_count_record_G >= (int)vec.size() / 2) {
i_medianImg_G = index_record;
}
last_count_record_G = current_count_record_G;
}
if (record_element_R[index_record] >= 1) {
current_count_record_R += record_element_R[index_record];
if (last_count_record_R < (int)vec.size() / 2 && current_count_record_R >= (int)vec.size() / 2) {
i_medianImg_R = index_record;
}
last_count_record_R = current_count_record_R;
}
if (i_medianImg_B >= 0 && i_medianImg_G >= 0 && i_medianImg_R >= 0) {
break;
}
}
if (i_medianImg_B >= 0)
medianImg.at<Vec3b>(row, col)[0] = i_medianImg_B;
else
medianImg.at<Vec3b>(row, col)[0] = 0;
if (i_medianImg_G >= 0)
medianImg.at<Vec3b>(row, col)[1] = i_medianImg_G;
else
medianImg.at<Vec3b>(row, col)[1] = 0;
if (i_medianImg_R >= 0)
medianImg.at<Vec3b>(row, col)[2] = i_medianImg_R;
else
medianImg.at<Vec3b>(row, col)[2] = 0;
}
/*else {
if (col >= 1) {
medianImg.at<Vec3b>(row, col)[0] = medianImg.at<Vec3b>(row, col - 1)[0];
medianImg.at<Vec3b>(row, col)[1] = medianImg.at<Vec3b>(row, col - 1)[1];
medianImg.at<Vec3b>(row, col)[2] = medianImg.at<Vec3b>(row, col - 1)[2];
}
else if(row >= 1) {
medianImg.at<Vec3b>(row, col)[0] = medianImg.at<Vec3b>(row - 1, col)[0];
medianImg.at<Vec3b>(row, col)[1] = medianImg.at<Vec3b>(row - 1, col)[1];
medianImg.at<Vec3b>(row, col)[2] = medianImg.at<Vec3b>(row - 1, col)[2];
}
}*/
}
}
//gettimeofday(&currtime, NULL);
//now_ms = (currtime.tv_sec * 1000) + (currtime.tv_usec / 1000); //單位為毫秒
//double dw_FPS_time_delta = (double)(now_ms - last_ms);
//dw_FPS_time_delta = abs((int)dw_FPS_time_delta);
//printf("\n-----compute median ms:%lf\n", dw_FPS_time_delta);
return medianImg;
}
int get_store_img_background_array_length_test() {
return store_img_background_array_length_test;
}
void release_img_background() {
//if (g_pMOG2 != nullptr) {
//g_pMOG2.release();
//}
//if (g_pMOG2_2 != nullptr) {
//g_pMOG2_2.release();
//}
// 清理記憶體
g_multiLayerMOG2.clearMemory();
g_multiLayerMOG2_2.clearMemory();
for (int i = 0; i < store_img_background_array_length; i++) {
if (!img_background_array[i].empty()) {
img_background_array[i].release();
}
}
for (int i = 0; i < store_img_background_array_length_test; i++) {
if (!img_background_array_test[i].empty()) {
img_background_array_test[i].release();
}
}
if (!img_background_short_term.empty()) {
img_background_short_term.release();
}
if (!img_background_long_term.empty()) {
img_background_long_term.release();
}
if (!img_median_short_term.empty())
img_median_short_term.release();
if (!img_median_long_term.empty())
img_median_long_term.release();
if (!img_background_short_term_yuv.empty())
img_background_short_term_yuv.release();
if (!img_background_long_term_yuv.empty())
img_background_long_term_yuv.release();
}
void run_compute_median() {
//pthread_detach(pthread_self());
if (strcmp(viewChannelData[0].ivs_mode, "3") == 0) {
}
else {
if (store_img_background_array_length >= MAX_SHORT_TERM && strcmp(viewChannelData[0].enable_unknown_object, "Yes") == 0) {
pthread_mutex_lock(&mutex_compute_median);
check_if_compute_median_finish = 0;
if (store_img_background_array_length >= MAX_SHORT_TERM) {
vector<Mat> frames_short;
vector<Mat> frames_long;
int size_short_term = MAX_SHORT_TERM <= store_img_background_array_length ? MAX_SHORT_TERM : store_img_background_array_length;
size_short_term -= (1 - (size_short_term % 2));
for (int i = 0; i < size_short_term; i++) {
int index_short_term = current_index_img_background_array - i;
if (index_short_term < 0) {
index_short_term = store_img_background_array_length + index_short_term;
}
//printf("\n---------index_short_term:%d:%d:%d\n", index_short_term, img_background_array[index_short_term].size().width, img_background_array[index_short_term].size().height);
if (!img_background_array[index_short_term].empty())
frames_short.push_back(img_background_array[index_short_term]);
//printf("\n---------frames_short:%d:%d:%d\n", i, frames_short[i].size().width, frames_short[i].size().height);
}
//printf("\ndiffer image-------14\n");
if (!img_median_short_term.empty())
img_median_short_term.release();
img_median_short_term = compute_median(frames_short);
//pthread_mutex_lock(&mutex_short_term_yuv);
if (!img_background_short_term_yuv.empty())
img_background_short_term_yuv.release();
cvtColor(img_median_short_term, img_background_short_term_yuv, CV_BGR2YUV);
//pthread_mutex_unlock(&mutex_short_term_yuv);
Mat img_gray_short_term;
//printf("\ndiffer image-------15\n");
//背景存放
//pthread_mutex_lock(&mutex_short_term);
if (!img_background_short_term.empty())
img_background_short_term.release();
cvtColor(img_median_short_term, img_gray_short_term, CV_BGR2GRAY);
img_background_short_term = img_gray_short_term.clone();
//blur(img_gray_short_term, img_background_short_term, Size(BLUR_SIZE, BLUR_SIZE));//5 5
//pthread_mutex_unlock(&mutex_short_term);
img_gray_short_term.release();
//printf("\ndiffer image-------16\n");
int size_long_term = MAX_LONG_TERM <= store_img_background_array_length ? MAX_LONG_TERM : store_img_background_array_length;
size_long_term -= (1 - (size_long_term % 2));
int ajust_size_long_term = size_short_term;
if (size_long_term < ajust_size_long_term) {
for (int i = 0; i < size_long_term; i++) {
int index_long_term = current_index_img_background_array - i;
if (index_long_term < 0) {
index_long_term = store_img_background_array_length + index_long_term;
}
//printf("\n---------index_long_term:%d:%d:%d\n", index_long_term, img_background_array[index_long_term].size().width, img_background_array[index_long_term].size().height);
if (!img_background_array[index_long_term].empty())
frames_long.push_back(img_background_array[index_long_term]);
//printf("\n---------frames_long:%d:%d:%d\n", i, frames_long[i].size().width, frames_long[i].size().height);
}
}
else {
float unit_between_i = (float)size_long_term / (float)ajust_size_long_term;
for (int i = 0; i < ajust_size_long_term; i++) {
int temp_i = (int)((unit_between_i*(float)i));
int index_long_term = current_index_img_background_array - temp_i;
if (index_long_term < 0) {
index_long_term = store_img_background_array_length + index_long_term;
}
//printf("\n---------index_long_term:%d:%d:%d\n", index_long_term, img_background_array[index_long_term].size().width, img_background_array[index_long_term].size().height);
if (!img_background_array[index_long_term].empty())
frames_long.push_back(img_background_array[index_long_term]);
//printf("\n---------frames_long:%d:%d:%d\n", i, frames_long[i].size().width, frames_long[i].size().height);
}
}
//printf("\ndiffer image-------17\n");
if (!img_median_long_term.empty())
img_median_long_term.release();
img_median_long_term = compute_median(frames_long);
//pthread_mutex_lock(&mutex_long_term_yuv);
if (!img_background_long_term_yuv.empty())
img_background_long_term_yuv.release();
cvtColor(img_median_short_term, img_background_long_term_yuv, CV_BGR2YUV);
//pthread_mutex_unlock(&mutex_long_term_yuv);
Mat img_gray_long_term;
//printf("\ndiffer image-------18\n");
//背景存放
//pthread_mutex_lock(&mutex_long_term);
if (!img_background_long_term.empty())
img_background_long_term.release();
cvtColor(img_median_long_term, img_gray_long_term, CV_BGR2GRAY);
img_background_long_term = img_gray_long_term.clone();
//blur(img_gray_long_term, img_background_long_term, Size(BLUR_SIZE, BLUR_SIZE));//5 5
//pthread_mutex_unlock(&mutex_long_term);
img_gray_long_term.release();
for (int i = 0; i < (int)frames_short.size(); i++) {
frames_short[i].release();
}
for (int i = 0; i < (int)frames_long.size(); i++) {
frames_long[i].release();
}
frames_short.clear();
frames_long.clear();
vector<Mat>().swap(frames_short);
vector<Mat>().swap(frames_long);
//printf("\n----------frames_short.size():%d\n",(int)frames_short.size());
/*
for (int i = 0; i < size_short_term; i++) {
int index_short_term = current_index_img_background_array - i;
if (index_short_term < 0) {
index_short_term = store_img_background_array_length + index_short_term;
}
printf("\n---------after free:index_short_term:%d:%d:%d\n", index_short_term, img_background_array[index_short_term].size().width, img_background_array[index_short_term].size().height);
}*/
}
check_if_compute_median_finish = 1;
pthread_mutex_unlock(&mutex_compute_median);
//printf("\ndiffer image-------19\n");
}
}
//pthread_exit(NULL);
}
//int index_rand = 0;
int differ_image_test(char *output_image, int* image_size, char * snaphd_image_buffer, int snaphd_image_size, int i_InSourceOri_w, int i_InSourceOri_h)
{
if (AI_fps <= 0) {
return 0;
}
else {
if (strcmp(viewChannelData[0].enable_unknown_object, "No") == 0) {
double temp_time_interval_with_msec = (double)(600.0) / ((double)MAX_SHORT_TERM_TEST - 1.0)*1000.0; //TIME_INTERVAL_WITH_MSEC
if (store_img_background_array_length_test < MAX_SHORT_TERM_TEST) {
temp_time_interval_with_msec = (double)(60.0) / ((double)MAX_SHORT_TERM_TEST - 1.0)*1000.0; //TIME_INTERVAL_WITH_MSEC
}
//int temp_AI_fps = AI_fps >= 2 ? AI_fps : 2;
current_ms_differ_image_test = getCurrentTime();
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
int ivs_width = 80;
int ivs_height = 45;
Mat temp_img_decode;
temp_img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\n-----%d,%d,%d,%d\n", temp_img_decode.size().width, i_InSourceOri_w, temp_img_decode.size().height, i_InSourceOri_h);
if (temp_img_decode.size().width != VIEW_WEB_WIDTH_HD || temp_img_decode.size().height != VIEW_WEB_HEIGHT_HD)
{
temp_img_decode.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
}
else {
Mat img_decode;
resize(temp_img_decode, img_decode, Size(ivs_width, ivs_height), INTER_NEAREST);
temp_img_decode.release();
Mat img_gray;
cvtColor(img_decode, img_gray, CV_BGR2GRAY);
float ratio_width = (float)i_InSourceOri_w / (float)ivs_width;
float ratio_height = (float)i_InSourceOri_h / (float)ivs_height;
#if 1
//過濾時間banner
{
int mask_width = ivs_width;
int mask_height = ivs_height;
int banner_filter = 2;
Mat imageMask(mask_height, mask_width, CV_8UC3, Scalar(0, 0, 0));
imageMask(Rect(0, banner_filter, mask_width, mask_height - banner_filter)) = Scalar(255, 255, 255); //make rectangle 1
Mat imageMask_gray;
cvtColor(imageMask, imageMask_gray, CV_BGR2GRAY);
imageMask.release();
Mat maskedImage;
bitwise_and(img_gray, imageMask_gray, maskedImage);
imageMask_gray.release();
img_gray.release();
img_gray = maskedImage.clone();
maskedImage.release();
}
#endif
Mat currFrame;
currFrame = img_gray.clone();
Mat currFrame_blur;
GaussianBlur(currFrame, currFrame_blur, Size(3, 3), 0);
if (last_ms_differ_image_test == 0 || current_ms_differ_image_test - last_ms_differ_image_test >= (long)temp_time_interval_with_msec) {
if (store_img_background_array_length_test < MAX_TIME_LENGTH_TEST) {
if (store_img_background_array_length_test == 0) {
last_ms_differ_image_test = 0;
}
img_background_array_test[store_img_background_array_length_test] = currFrame_blur.clone();
current_index_img_background_array_test = store_img_background_array_length_test;
store_img_background_array_length_test++;
}
else {
if ((int)((current_ms_differ_image_test - last_ms_differ_image_test) / (long)temp_time_interval_with_msec) >= 1) {
//differ_image會根據如果compute_median_thread的計算太久時,會多學當下背景幾張。
for (int count_vir = 0; count_vir < (int)((current_ms_differ_image_test - last_ms_differ_image_test) / (long)temp_time_interval_with_msec); count_vir++) {
img_background_array_test[virtual_index_img_background_array_test].release();
img_background_array_test[virtual_index_img_background_array_test] = currFrame_blur.clone();
current_index_img_background_array_test = virtual_index_img_background_array_test;
virtual_index_img_background_array_test++;
if (virtual_index_img_background_array_test >= MAX_TIME_LENGTH_TEST) {
virtual_index_img_background_array_test = 0;
}
}
}
else {
img_background_array_test[virtual_index_img_background_array_test].release();
img_background_array_test[virtual_index_img_background_array_test] = currFrame_blur.clone();
current_index_img_background_array_test = virtual_index_img_background_array_test;
virtual_index_img_background_array_test++;
if (virtual_index_img_background_array_test >= MAX_TIME_LENGTH_TEST) {
virtual_index_img_background_array_test = 0;
}
}
}
if (last_ms_differ_image_test == 0) {
last_ms_differ_image_test = current_ms_differ_image_test;
}
else {
if ((int)((current_ms_differ_image_test - last_ms_differ_image_test) / (long)temp_time_interval_with_msec) >= 1) {
for (int count_vir = 0; count_vir < (int)((current_ms_differ_image_test - last_ms_differ_image_test) / (long)temp_time_interval_with_msec); count_vir++) {
last_ms_differ_image_test = last_ms_differ_image_test + (long)temp_time_interval_with_msec;
}
}
else {
last_ms_differ_image_test = last_ms_differ_image_test + (long)temp_time_interval_with_msec;
}
}
}
if (store_img_background_array_length_test >= MAX_SHORT_TERM_TEST) {
// 初始化
#if 1
Mat img_thres;
double thresh = 25;//25
int maxVal = 255;
threshold(currFrame_blur, img_thres, thresh, maxVal, THRESH_BINARY);////THRESH_OTSU THRESH_BINARY
int dilation_size = 1;
Mat element = getStructuringElement(MORPH_RECT, Size(2 * dilation_size + 1, 2 * dilation_size + 1), Point(dilation_size, dilation_size));
Mat recorded_map = Mat::zeros(img_thres.size(), img_thres.type());
img_thres.release();
#endif
//將其餘的影像逐一進行位元或操作
//i = 0
for (int i = 0; i < MAX_SHORT_TERM_TEST - (int)(MAX_SHORT_TERM_TEST / 2); i++) {
int index_mat = current_index_img_background_array_test - i;
int index_mat_shift = current_index_img_background_array_test - i - (int)(MAX_SHORT_TERM_TEST / 2);
if (index_mat < 0) {
index_mat = MAX_TIME_LENGTH_TEST - 1;
}
if (index_mat_shift < 0) {
index_mat_shift = MAX_TIME_LENGTH_TEST - 1;
}
Mat img_absdiff_temp, img_thres_temp, img_dilated_temp, img_eroded_temp;
absdiff(img_background_array_test[index_mat], img_background_array_test[index_mat_shift], img_absdiff_temp);
threshold(img_absdiff_temp, img_thres_temp, thresh, maxVal, THRESH_BINARY);////THRESH_OTSU THRESH_BINARY
img_absdiff_temp.release();
erode(img_thres_temp, img_eroded_temp, element);
img_thres_temp.release();
dilate(img_eroded_temp, img_dilated_temp, element);
img_eroded_temp.release();
recorded_map += (img_dilated_temp * 2.5 / MAX_SHORT_TERM_TEST);//2.5
img_dilated_temp.release();
}
element.release();
if (i_InSourceOri_h >= 1 && i_InSourceOri_w >= 1 && g_framesize_height >= 1 && g_framesize_width >= 1)
{
float temp_framsize_height = (float)g_framesize_height;
float temp_framsize_width = (float)g_framesize_width;
float temp_g_ori_yuv_height = (float)i_InSourceOri_h;
float temp_g_ori_yuv_width = (float)i_InSourceOri_w;
float ratio_height_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_height / temp_framsize_height;
float ratio_width_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_width / temp_framsize_width;
float thres_x_min = 0.0;
float thres_x_max = 1.0;
float thres_y_min = 0.0;
float thres_y_max = 1.0;
float cut_thres_ratio = 0.0;
if (g_check_if_OK_thermal == 0 && g_IsPTZDevice == 1 && strcmp(SystemSetting.enable_crop_mode, "Yes") == 0)
{
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_height * temp_framsize_width) / (temp_framsize_height*temp_g_ori_yuv_width);
thres_x_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_x_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
else if (ratio_width_g_ori_yuv_to_ai_webpage < ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_width * temp_framsize_height) / (temp_framsize_width*temp_g_ori_yuv_height);
thres_y_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_y_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
}
vector<Rect> store_rect_contours;
int contours_size = 0;
//for (int index_slice = 1; index_slice < MAX_SLICE_SIZE; index_slice++)
{
Mat slice_map;
int index_slice = 1;
vector<vector<Point>> contours;
double thresh_slice = 25 + ((maxVal - 25) / (MAX_SLICE_SIZE)) * index_slice;
threshold(recorded_map, slice_map, thresh_slice, maxVal, THRESH_BINARY);////THRESH_OTSU THRESH_BINARY
findContours(slice_map, contours, noArray(), RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
slice_map.release();
if (g_check_if_OK_thermal == 0 && g_IsPTZDevice == 1 && strcmp(SystemSetting.enable_crop_mode, "Yes") == 0)
{
for (int i = 0; i < (int)contours.size(); i++) {
Rect temp_rect = boundingRect(contours[i]);
if (temp_rect.area() < 10)//50
{
}
else {
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
//float rect_center_x = rect_left_x + rect_width / 2.0;
//float rect_center_y = rect_top_y + rect_height / 2.0;
float obj_x_max = (rect_left_x + rect_width) / temp_g_ori_yuv_width;
float obj_x_min = rect_left_x / temp_g_ori_yuv_width;
float obj_y_max = (rect_top_y + rect_height) / temp_g_ori_yuv_height;
float obj_y_min = rect_top_y / temp_g_ori_yuv_height;
if (obj_x_max <= thres_x_min ||
obj_x_min >= thres_x_max ||
obj_y_max <= thres_y_min ||
obj_y_min >= thres_y_max)
{
}
else {
if (obj_x_min < thres_x_min) {
obj_x_min = thres_x_min;
}
if (obj_x_max > thres_x_max) {
obj_x_max = thres_x_max;
}
if (obj_y_min < thres_y_min) {
obj_y_min = thres_y_min;
}
if (obj_y_max > thres_y_max) {
obj_y_max = thres_y_max;
}
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
float obj_center_x = (obj_x_min + obj_x_max) / 2.0;
float obj_width = (obj_x_max - obj_x_min);
obj_center_x = (obj_center_x - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_width = obj_width * (1.0 / cut_thres_ratio);
obj_x_min = obj_center_x - obj_width / 2.0;
obj_x_max = obj_center_x + obj_width / 2.0;
}
else {
float obj_center_y = (obj_y_min + obj_y_max) / 2.0;
float obj_height = (obj_y_max - obj_y_min);
obj_center_y = (obj_center_y - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_height = obj_height * (1.0 / cut_thres_ratio);
obj_y_min = obj_center_y - obj_height / 2.0;
obj_y_max = obj_center_y + obj_height / 2.0;
}
if (obj_x_min < 0.0)
obj_x_min = 0.0;
if (obj_x_max > 1.0)
obj_x_max = 1.0;
if (obj_y_min < 0.0)
obj_y_min = 0.0;
if (obj_y_max > 1.0)
obj_y_max = 1.0;
obj_x_min = obj_x_min * (float)i_InSourceOri_w; //1920
obj_x_max = obj_x_max * (float)i_InSourceOri_w; //1920
obj_y_min = obj_y_min * (float)i_InSourceOri_h; //1080
obj_y_max = obj_y_max * (float)i_InSourceOri_h; //1080
rect_left_x = obj_x_min;
rect_top_y = obj_y_min;
rect_width = (obj_x_max - obj_x_min);
rect_height = (obj_y_max - obj_y_min);
//rect_center_x = rect_left_x + rect_width / 2.0;
//rect_center_y = rect_top_y + rect_height / 2.0;
store_rect_contours.push_back(temp_rect);
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
}
contours[i].clear();
vector<Point>().swap(contours[i]);
}
//printf("\n----#1---[%d]%d\n", index_slice,contours_size);
}
else {
for (int i = 0; i < (int)contours.size(); i++) {
Rect temp_rect = boundingRect(contours[i]);
if (temp_rect.area() < 10)//50
{
}
else {
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
//float rect_center_x = rect_left_x + rect_width / 2.0;
//float rect_center_y = rect_top_y + rect_height / 2.0;
store_rect_contours.push_back(temp_rect);
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
contours[i].clear();
vector<Point>().swap(contours[i]);
}
//printf("\n----#2---[%d]%d\n", index_slice, contours_size);
}
contours.clear();
vector<vector<Point>>().swap(contours);
}
if (contours_size >= 1) {
vector<Rect> mergedRectangles;
for (int i = 0; i < ((int)store_rect_contours.size()) - 1; i++) {
Rect rect1 = store_rect_contours[i];
if (rect1.width >= 1 && rect1.height >= 1) {
//Mat slice1 = slice_map(rect1); // 提取子矩陣
//double BlackRatio_1 = sum(slice1 == 0)[0] / double(rect1.width*rect1.height);
//slice1.release();
int merge_ok = 0;
for (int j = i + 1; j < (int)store_rect_contours.size(); j++) {
Rect rect2 = store_rect_contours[j];
if (rect2.width >= 1 && rect2.height >= 1) {
Rect unionRect = rect1 & rect2;
double unionArea = double(unionRect.width*unionRect.height);
if (unionArea >= 1) {
{
//Mat sliceUnion = slice_map(unionRect); // 提取聯集的子矩陣
//double BlackRatio_sum = sum(sliceUnion == 0)[0] / unionArea;
//sliceUnion.release();
//if (BlackRatio_sum >= BlackRatio_1)
{
rect1 = unionRect; // Merge rect2 into rect1
//store_rect_contours[i] = rect1;
//store_rect_contours[j] = Rect();
mergedRectangles.push_back(rect1);
merge_ok = 1;
}
}
}
}
}
if (merge_ok == 0) {
mergedRectangles.push_back(rect1); // Add non-merged rectangle to result
}
}
}
store_rect_contours.clear();
vector<Rect>().swap(store_rect_contours);
//printf("\n-----------total_num:%d\n", (int)mergedRectangles.size());
#if 0
for (int i = 0; i < (int)mergedRectangles.size(); i++) {
for (int index_motion = 0; index_motion < MAX_MOTION_AREA; index_motion++) {
if (g_Motion_Area_Data[index_motion].used == 0 && g_Motion_Area_Data[index_motion].locked == 0) {
g_Motion_Area_Data[index_motion].locked = 1;
g_Motion_Area_Data[index_motion].box_x = ((float)(mergedRectangles[i].x))*ratio_width;
g_Motion_Area_Data[index_motion].box_y = ((float)(mergedRectangles[i].y))*ratio_height;
g_Motion_Area_Data[index_motion].box_w = ((float)(mergedRectangles[i].width))*ratio_width;
g_Motion_Area_Data[index_motion].box_h = ((float)(mergedRectangles[i].height))*ratio_height;
g_Motion_Area_Data[index_motion].used = 1;
g_Motion_Area_Data[index_motion].locked = 0;
break;
}
}
}
#endif
if (*image_size == 0) {
for (const Rect& a_rect : mergedRectangles) {
rectangle(recorded_map, a_rect, Scalar(255, 255, 255), 2);
}
}
mergedRectangles.clear();
vector<Rect>().swap(mergedRectangles);
}
}
#if 1
//char file_path_jpeg[256] = { 0 };
//sprintf(file_path_jpeg, "/emmc/plugin/Aida_data/storage/output_image_%d.jpeg", index_rand);
//index_rand++;
//if (index_rand == 20) {
//index_rand = 0;
//}
//imwrite(file_path_jpeg, recorded_map);
if (*image_size == 0) {
vector<uchar> data_encode;
imencode(".jpeg", recorded_map, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
#endif
recorded_map.release();
}
currFrame.release();
currFrame_blur.release();
img_gray.release();
img_decode.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
}
}
return 0;
}
}
int differ_image(char *output_image,int* image_size,char * snaphd_image_buffer, int snaphd_image_size, detection_pos* PosInfo, int i_InSourceOri_w, int i_InSourceOri_h,int draw_img_long, int draw_img_short,int* no_tempering, int not_to_show_tempering) // For normal type
{
if (AI_fps <= 0 || strcmp(viewChannelData[0].enable_unknown_object, "No") == 0 || check_if_compute_median_finish == 0) {
return 0;
}
else {
//printf("\ndiffer_image--------------------start-----1\n");
detection_pos* pNext = NULL;
double temp_time_interval_with_msec = (double)atoi(viewChannelData[0].dwell_unknown_object) / ((double)MAX_SHORT_TERM - 1.0)*1000.0; //TIME_INTERVAL_WITH_MSEC
//printf("\n------temp_time_interval_with_msec:%lf\n", temp_time_interval_with_msec);
//printf("\nTTTTTTTTT no_tempering:%d\n", *no_tempering);
int temp_AI_fps = AI_fps >= 2 ? AI_fps : 2;
//printf("\nTTTTTTTTTT i_InSourceOri_w:%d , i_InSourceOri_h:%d\n", i_InSourceOri_w, i_InSourceOri_h);
//printf("\ndiffer image-------1\n");
current_ms_differ_image = getCurrentTime();
//printf("\n-------------%ld\n", current_ms_differ_image);
//printf("\nTTTTTTTTTT ratio_width:%f , ratio_height:%f\n", ratio_width, ratio_height);
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_gray;
Mat img_blur;
Mat img_thres;
//Mat img_morph_open_one;
//Mat img_morph_open_twice;
//Mat img_morph_close_one;
Mat img_morph_close_twice;
Mat img_absdiff;
Mat bitwise_and_before_contours;
Mat short_term_contours;
Mat long_term_contours;
//vector<Mat> img_channels;
uint32_t valid_bbox_idx = 0;
Mat img_absdiff_short_term;
Mat img_blur_short_term;
Mat img_absdiff_long_term;
Mat img_blur_long_term;
Mat img_yuv;
Mat img_blur_yuv;
Mat masked_certain;
int thres_light[3] = { 0 };//25
////////////將原本要送到網頁char * decode成mat
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
Mat temp_img_decode;
temp_img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\ndiffer image-------2\n");
int ivs_width = 80;
int ivs_height = 45;
float ratio_width = (float)i_InSourceOri_w / (float)ivs_width;
float ratio_height = (float)i_InSourceOri_h / (float)ivs_height;
//printf("\n-----%d,%d,%d,%d\n", temp_img_decode.size().width, i_InSourceOri_w, temp_img_decode.size().height, i_InSourceOri_h);
if (temp_img_decode.size().width != VIEW_WEB_WIDTH_HD || temp_img_decode.size().height != VIEW_WEB_HEIGHT_HD)
{
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
temp_img_decode.release();
return 0;
}
else
{
Mat img_decode;
resize(temp_img_decode, img_decode, Size(ivs_width, ivs_height), INTER_NEAREST);
temp_img_decode.release();
/////////////從此開始為opencv基本影像計算
//printf("\ndiffer_image--------------------start-----1-------1\n");
if (check_if_tempering_many_times == -100) {
check_if_tempering_many_times = (temp_AI_fps - 1) * 4;
}
//灰階化
cvtColor(img_decode, img_gray, CV_BGR2GRAY);
//printf("\ndiffer_image--------------------start-----1-------2\n");
#if 1
//過濾時間banner
{
int mask_width = ivs_width;
int mask_height = ivs_height;
Mat imageMask(mask_height, mask_width, CV_8UC3, Scalar(0, 0, 0));
imageMask(Rect(0, 2, mask_width, mask_height-2)) = Scalar(255, 255, 255); //make rectangle 1
Mat imageMask_gray;
cvtColor(imageMask, imageMask_gray, CV_BGR2GRAY);
imageMask.release();
Mat maskedImage;
bitwise_and(img_gray, imageMask_gray, maskedImage);
imageMask_gray.release();
img_gray.release();
img_gray = maskedImage.clone();
maskedImage.release();
}
#endif
//printf("\ndiffer_image--------------------start-----1-------3\n");
//split(img_decode, img_channels);
//Mat abs_r_g = abs(img_channels[2] - img_channels[1]);
//Mat abs_r_b = abs(img_channels[2] - img_channels[0]);
//Mat abs_g_b = abs(img_channels[1] - img_channels[0]);
//double r_g = countNonZero(abs_r_g);
//double r_b = countNonZero(abs_r_b);
//double g_b = countNonZero(abs_g_b);
//abs_r_g.release();
//abs_r_b.release();
//abs_g_b.release();
//img_channels[0].release();
//img_channels[1].release();
//img_channels[2].release();
//img_channels.clear();
//vector<Mat>().swap(img_channels);
//double ratio_determine_if_color = (r_g + r_b + g_b) / ((double)ivs_width*(double)ivs_height);
//printf("\n-------imageDnData.current_day_or_night_mode:%d\n", imageDnData.current_day_or_night_mode);
//printf("\n-------imageDnData.check_if_switch_happene[0]:%d\n", imageDnData.check_if_switch_happened[0]);
//printf("\ndiffer_image--------------------start-----1-------4\n");
//if (not_to_show_tempering == 0) {
//if (imageDnData.current_day_or_night_mode == 1) {
//printf("\nimage is color:%lf\n", ratio_determine_if_color);
//last_day_or_night_mode = current_day_or_night_mode;
//current_day_or_night_mode = 1;
//}
//else {
//printf("\nimage is grayscale:%lf\n", ratio_determine_if_color);
//last_day_or_night_mode = current_day_or_night_mode;
//current_day_or_night_mode = 2;
//}
//}
thres_light[0] = 6;//80 //8
thres_light[1] = 0;//25 //3
thres_light[2] = 0;//25 //3
if (strcmp(viewChannelData[0].ivs_mode, "0") == 0) {
thres_light[0] = 6;//80 //8
}
else if (strcmp(viewChannelData[0].ivs_mode, "1") == 0) {
thres_light[0] = 4;//80 //8
}
else if (strcmp(viewChannelData[0].ivs_mode, "2") == 0) {
thres_light[0] = 2;//80 //8
}
//模糊化
img_blur = img_gray.clone();
//blur(img_gray, img_blur, Size(BLUR_SIZE, BLUR_SIZE));//5 5
//GaussianBlur(img_gray, img_blur, Size(4, 4),0,0);
img_gray.release();
//printf("\ndiffer_image--------------------start-----1-------5\n");
if (img_blur.size().width == 0 || img_blur.size().height == 0) {
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
img_blur.release();
return 0;
}
else
{
//printf("\ndiffer_image--------------------start-----1-------6\n");
//printf("\ndiffer image-------3\n");
//存img_decode到時間軸上面
//printf("\n--------check_if_compute_median_finish:%d,check_if_tempering_happened:%d\n", check_if_compute_median_finish, check_if_tempering_happened);
//printf("\n----current_ms_differ_image - last_ms_differ_image:%ld\n", current_ms_differ_image - last_ms_differ_image);
//printf("\n--------(current_ms_differ_image - last_ms_differ_image) / temp_time_interval_with_msec : %d\n",
//(int)((current_ms_differ_image - last_ms_differ_image)/ (long)temp_time_interval_with_msec));
if (last_ms_differ_image == 0 || current_ms_differ_image - last_ms_differ_image >= (long)temp_time_interval_with_msec) {
if (check_if_compute_median_finish == 1 && check_if_tempering_happened <= 0) {
if (store_img_background_array_length < MAX_TIME_LENGTH) {
if (store_img_background_array_length == 0) {
last_ms_differ_image = 0;
}
img_background_array[store_img_background_array_length] = img_decode.clone();
current_index_img_background_array = store_img_background_array_length;
store_img_background_array_length++;
}
else {
if ((int)((current_ms_differ_image - last_ms_differ_image) / (long)temp_time_interval_with_msec) >= 1) {
//differ_image會根據如果compute_median_thread的計算太久時,會多學當下背景幾張。
for (int count_vir = 0; count_vir < (int)((current_ms_differ_image - last_ms_differ_image) / (long)temp_time_interval_with_msec); count_vir++) {
img_background_array[virtual_index_img_background_array].release();
img_background_array[virtual_index_img_background_array] = img_decode.clone();
current_index_img_background_array = virtual_index_img_background_array;
virtual_index_img_background_array++;
if (virtual_index_img_background_array >= MAX_TIME_LENGTH) {
virtual_index_img_background_array = 0;
}
}
}
else {
img_background_array[virtual_index_img_background_array].release();
img_background_array[virtual_index_img_background_array] = img_decode.clone();
current_index_img_background_array = virtual_index_img_background_array;
virtual_index_img_background_array++;
if (virtual_index_img_background_array >= MAX_TIME_LENGTH) {
virtual_index_img_background_array = 0;
}
}
}
if (last_ms_differ_image == 0) {
last_ms_differ_image = current_ms_differ_image;
}
else {
if ((int)((current_ms_differ_image - last_ms_differ_image) / (long)temp_time_interval_with_msec) >= 1) {
for (int count_vir = 0; count_vir < (int)((current_ms_differ_image - last_ms_differ_image) / (long)temp_time_interval_with_msec); count_vir++) {
last_ms_differ_image = last_ms_differ_image + (long)temp_time_interval_with_msec;
}
}
else {
last_ms_differ_image = last_ms_differ_image + (long)temp_time_interval_with_msec;
}
}
}
}
//printf("\ndiffer_image--------------------start-----1-------7\n");
if (check_if_tempering_happened <= 0) {
if (store_img_background_array_length < MAX_SHORT_TERM) {
*no_tempering = 0;
check_if_tempering_many_times = (temp_AI_fps - 1) * 4;
g_progress_bar = (float)100.0 * (float)store_img_background_array_length / (float)MAX_SHORT_TERM;
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
img_blur.release();
/*if (PosInfo != NULL && bg_learning_first_to_show == 0) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "bg_learning");
pNext->confidence = (float)sqrt((double)1.0 * (double)100)*10.0;
pNext->progress_bar = (float)100.0 * (float)store_img_background_array_length / (float)MAX_SHORT_TERM;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = (float)ivs_width * (float)ratio_width * (float)0.35;//0.03
pNext->top_y = (float)ivs_height * (float)ratio_height * (float)0.35;//0.1
pNext->width = (float)ivs_width * (float)ratio_width * (float)0.3;//0.05
pNext->height = (float)ivs_height * (float)ratio_height * (float)0.3;//0.05
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}*/
return (int)valid_bbox_idx;
}
}
else if (check_if_tempering_happened >= 1) {
g_progress_bar = 1.0;
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
img_blur.release();
if (!img_background_short_term_yuv.empty())
img_background_short_term_yuv.release();
if (!img_background_long_term_yuv.empty())
img_background_long_term_yuv.release();
if (PosInfo != NULL && not_to_show_tempering == 0) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "tampering");
pNext->confidence = (float)sqrt((double)1.0 * (double)100)*10.0;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = (float)ivs_width * ratio_width * (float)0.35;
pNext->top_y = (float)ivs_height * ratio_height * (float)0.35;
pNext->width = (float)ivs_width * ratio_width * (float)0.3;
pNext->height = (float)ivs_height * ratio_height * (float)0.3;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
check_if_tempering_happened--;
return (int)valid_bbox_idx;
}
//printf("\ndiffer_image--------------------start-----2\n");
//bg_learning_first_to_show = 1;
g_progress_bar = 0.0;
//printf("\ndiffer image-------4\n");
//計算兩影像差異//short term
//if (get_check_if_existing_any_switch_happened() == 0 || store_img_background_array_length <= MAX_SIZE_SWITCH_HAPPENED)
{
if (!img_background_short_term.empty() && !img_background_short_term_yuv.empty()) {
absdiff(img_blur, img_background_short_term, img_absdiff);
}
else {
img_absdiff = Mat::zeros(img_blur.size(), img_blur.type());
}
}
#if 0
else {
if (imageDnData.check_if_switch_happened[MAX_SIZE_SWITCH_HAPPENED - 1] == 1) {
Mat gray_last_frame;
Mat blur_last_frame;
int index_last_frame;
if (current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1) >= 0) {
index_last_frame = current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1);
}
else {
index_last_frame = current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1) + store_img_background_array_length;
}
cvtColor(img_background_array[index_last_frame], gray_last_frame, CV_BGR2GRAY);
blur_last_frame = gray_last_frame.clone();
//blur(gray_last_frame, blur_last_frame, Size(BLUR_SIZE, BLUR_SIZE));//5 5
absdiff(img_blur, blur_last_frame, img_absdiff);
gray_last_frame.release();
blur_last_frame.release();
}
else {
img_absdiff = Mat::zeros(img_blur.size(), img_blur.type());
}
}
#endif
//二值化 THRESH_OTSU會自動找最佳閥值
double thresh = 25;//25
int maxVal = 255;
//double new_threshold = 0;
/*new_threshold =*/
threshold(img_absdiff, img_thres, thresh, maxVal, THRESH_BINARY);////THRESH_OTSU THRESH_BINARY
//膨脹侵蝕
//Mat morph_matrix = getStructuringElement(MORPH_RECT, Size(9, 5), Point(-1, -1)); //5 5
Mat morph_matrix = getStructuringElement(MORPH_RECT, Size(5, 3), Point(-1, -1));
//morphologyEx(img_thres, img_morph_close_twice, CV_MOP_CLOSE, morph_matrix);//CV_MOP_OPEN
img_morph_close_twice = img_thres.clone();
//morphologyEx(img_thres, img_morph_open_one, CV_MOP_OPEN, morph_matrix);//CV_MOP_OPEN
//morphologyEx(img_morph_open_one, img_morph_open_twice, CV_MOP_OPEN, morph_matrix);//CV_MOP_OPEN
//morphologyEx(img_morph_open_twice, img_morph_close_one, CV_MOP_CLOSE, morph_matrix);
//morphologyEx(img_morph_close_one, img_morph_close_twice, CV_MOP_CLOSE, morph_matrix);
if (!img_morph_close_twice.empty() && img_morph_close_twice.size().width >= 1 && img_morph_close_twice.size().height >= 1) {
short_term_contours = img_morph_close_twice.clone();
//short_term_contours = img_thres.clone();
}
else
short_term_contours = Mat::zeros(img_blur.size(), img_blur.type());
img_absdiff.release();
img_thres.release();
img_morph_close_twice.release();
//img_morph_close_one.release();
//img_morph_open_twice.release();
//img_morph_open_one.release();
//計算兩影像差異//long term
//if (get_check_if_existing_any_switch_happened() == 0 || store_img_background_array_length <= MAX_SIZE_SWITCH_HAPPENED)
{
if (!img_background_long_term.empty() && !img_background_long_term_yuv.empty()) {
absdiff(img_blur, img_background_long_term, img_absdiff);
}
else {
img_absdiff = Mat::zeros(img_blur.size(), img_blur.type());
}
}
#if 0
else {
if (imageDnData.check_if_switch_happened[MAX_SIZE_SWITCH_HAPPENED - 1] == 1) {
Mat gray_last_frame;
Mat blur_last_frame;
int index_last_frame;
if (current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1) >= 0) {
index_last_frame = current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1);
}
else {
index_last_frame = current_index_img_background_array - (GAP_SWITCH_HAPPENED - 1) + store_img_background_array_length;
}
cvtColor(img_background_array[index_last_frame], gray_last_frame, CV_BGR2GRAY);
blur_last_frame = gray_last_frame.clone();
//blur(gray_last_frame, blur_last_frame, Size(BLUR_SIZE, BLUR_SIZE));//5 5
absdiff(img_blur, blur_last_frame, img_absdiff);
gray_last_frame.release();
blur_last_frame.release();
}
else {
img_absdiff = Mat::zeros(img_blur.size(), img_blur.type());
}
}
#endif
//二值化 THRESH_OTSU會自動找最佳閥值
threshold(img_absdiff, img_thres, thresh, maxVal, THRESH_BINARY);//THRESH_OTSU THRESH_BINARY
//膨脹侵蝕
//morphologyEx(img_thres, img_morph_close_twice, CV_MOP_CLOSE, morph_matrix);//CV_MOP_OPEN
img_morph_close_twice = img_thres.clone();
//morphologyEx(img_thres, img_morph_open_one, CV_MOP_OPEN, morph_matrix);//CV_MOP_OPEN
//morphologyEx(img_morph_open_one, img_morph_open_twice, CV_MOP_OPEN, morph_matrix);//CV_MOP_OPEN
//morphologyEx(img_morph_open_twice, img_morph_close_one, CV_MOP_CLOSE, morph_matrix);
//morphologyEx(img_morph_close_one, img_morph_close_twice, CV_MOP_CLOSE, morph_matrix);
if (!img_morph_close_twice.empty() && img_morph_close_twice.size().width >= 1 && img_morph_close_twice.size().height >= 1) {
long_term_contours = img_morph_close_twice.clone();
//long_term_contours = img_thres.clone();
}
else
long_term_contours = Mat::zeros(img_blur.size(), img_blur.type());
img_absdiff.release();
img_thres.release();
morph_matrix.release();
img_morph_close_twice.release();
//img_morph_close_one.release();
//img_morph_open_twice.release();
//img_morph_open_one.release();
///////////////YUV檢查U值
cvtColor(img_decode, img_yuv, CV_BGR2YUV);
img_blur_yuv = img_yuv.clone();
//blur(img_yuv, img_blur_yuv, Size(BLUR_SIZE, BLUR_SIZE));//5 5
if (!img_background_short_term_yuv.empty())
{
img_blur_short_term = img_background_short_term_yuv.clone();
//blur(img_background_short_term_yuv, img_blur_short_term, Size(BLUR_SIZE, BLUR_SIZE));//5 5
}
if (!img_background_long_term_yuv.empty())
{
img_blur_long_term = img_background_long_term_yuv.clone();
//blur(img_background_long_term_yuv, img_blur_long_term, Size(BLUR_SIZE, BLUR_SIZE));//5 5
}
if (!img_blur_short_term.empty() && !img_blur_long_term.empty() /*&& get_check_if_existing_any_switch_happened()==0*/)
{
vector<Mat> img_channels_short_term;
vector<Mat> img_channels_long_term;
Mat bitwise_temp1;
Mat bitwise_temp2;
Mat bitwise_temp3;
Mat bitwise_temp_temp;
vector<Mat> img_channels_certain_short_term;
Mat merge_certain_short_term;
Mat inrange_short_term;
vector<Mat> img_channels_certain_long_term;
Mat merge_certain_long_term;
Mat inrange_long_term;
absdiff(img_blur_yuv, img_blur_short_term, img_absdiff_short_term);
absdiff(img_blur_yuv, img_blur_long_term, img_absdiff_long_term);
split(img_absdiff_short_term, img_channels_short_term);
split(img_absdiff_long_term, img_channels_long_term);
for (int color_index = 0; color_index < 3; color_index++) {
img_channels_certain_short_term.push_back(img_channels_short_term[color_index]);
img_channels_certain_short_term.push_back(img_channels_short_term[color_index]);
img_channels_certain_short_term.push_back(img_channels_short_term[color_index]);
img_channels_certain_long_term.push_back(img_channels_long_term[color_index]);
img_channels_certain_long_term.push_back(img_channels_long_term[color_index]);
img_channels_certain_long_term.push_back(img_channels_long_term[color_index]);
merge(img_channels_certain_short_term, merge_certain_short_term);
inRange(merge_certain_short_term, Scalar(thres_light[color_index], thres_light[color_index], thres_light[color_index]), Scalar(255, 255, 255), inrange_short_term);
merge(img_channels_certain_long_term, merge_certain_long_term);
inRange(merge_certain_long_term, Scalar(thres_light[color_index], thres_light[color_index], thres_light[color_index]), Scalar(255, 255, 255), inrange_long_term);
if (color_index == 0)
bitwise_and(inrange_short_term, inrange_long_term, bitwise_temp1);
else if (color_index == 1)
bitwise_and(inrange_short_term, inrange_long_term, bitwise_temp2);
else
bitwise_and(inrange_short_term, inrange_long_term, bitwise_temp3);
img_channels_certain_short_term[0].release();
img_channels_certain_short_term[1].release();
img_channels_certain_short_term[2].release();
img_channels_certain_short_term.clear();
vector<Mat>().swap(img_channels_certain_short_term);
img_channels_certain_long_term[0].release();
img_channels_certain_long_term[1].release();
img_channels_certain_long_term[2].release();
img_channels_certain_long_term.clear();
vector<Mat>().swap(img_channels_certain_long_term);
merge_certain_short_term.release();
inrange_short_term.release();
merge_certain_long_term.release();
inrange_long_term.release();
}
bitwise_or(bitwise_temp1, bitwise_temp2, bitwise_temp_temp);
bitwise_or(bitwise_temp3, bitwise_temp_temp, masked_certain);
bitwise_temp1.release();
bitwise_temp2.release();
bitwise_temp3.release();
bitwise_temp_temp.release();
img_channels_short_term[0].release();
img_channels_short_term[1].release();
img_channels_short_term[2].release();
img_channels_short_term.clear();
vector<Mat>().swap(img_channels_short_term);
img_channels_long_term[0].release();
img_channels_long_term[1].release();
img_channels_long_term[2].release();
img_channels_long_term.clear();
vector<Mat>().swap(img_channels_long_term);
img_absdiff_short_term.release();
img_absdiff_long_term.release();
}
else
{
masked_certain = Mat::zeros(img_blur_yuv.size(), CV_8UC1);
}
//printf("\ndiffer image-------5\n");
//Mat temp_bitwise;
//bitwise_not(short_term_contours, temp_bitwise);
bitwise_and(short_term_contours, long_term_contours, bitwise_and_before_contours);
//temp_bitwise.release();
//printf("\ndiffer image-------6\n");
img_blur.release();
vector<vector<Point>> contours;
vector<Rect> store_rect_contours;
vector<Rect> combine_rect_contours;
//vector<Rect>::iterator it_store_rect_contours;
vector<Rect> store_rect_contours_not_in_zone;
vector<Rect> store_ivs_object;
//printf("\ndiffer image-------7\n");
Rect draw_border_to_zero(0, 0, ivs_width, ivs_height);
rectangle(bitwise_and_before_contours,
draw_border_to_zero,
Scalar(0, 0, 0),
BORDER_WIDTH_TO_IGNORE_IVS, 8, 0);
rectangle(short_term_contours,
draw_border_to_zero,
Scalar(0, 0, 0),
BORDER_WIDTH_TO_IGNORE_IVS, 8, 0);
rectangle(long_term_contours,
draw_border_to_zero,
Scalar(0, 0, 0),
BORDER_WIDTH_TO_IGNORE_IVS, 8, 0);
findContours(bitwise_and_before_contours, contours, noArray(), RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Size inflationSize(2, 2);
Point inflationOffset(-1, -1);
int contours_size = 0;
int contours_size_not_in_zone = 0;
if (g_check_if_OK_thermal == 0 && g_IsPTZDevice == 1 && strcmp(SystemSetting.enable_crop_mode, "Yes") == 0) {
if (i_InSourceOri_h >= 1 && i_InSourceOri_w >= 1 && g_framesize_height >= 1 && g_framesize_width >= 1) {
float temp_framsize_height = (float)g_framesize_height;
float temp_framsize_width = (float)g_framesize_width;
float temp_g_ori_yuv_height = (float)i_InSourceOri_h;
float temp_g_ori_yuv_width = (float)i_InSourceOri_w;
float ratio_height_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_height / temp_framsize_height;
float ratio_width_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_width / temp_framsize_width;
float thres_x_min = 0.0;
float thres_x_max = 1.0;
float thres_y_min = 0.0;
float thres_y_max = 1.0;
float cut_thres_ratio = 0.0;
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_height * temp_framsize_width) / (temp_framsize_height*temp_g_ori_yuv_width);
thres_x_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_x_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
else if (ratio_width_g_ori_yuv_to_ai_webpage < ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_width * temp_framsize_height) / (temp_framsize_width*temp_g_ori_yuv_height);
thres_y_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_y_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
for (int i = 0; i < (int)contours.size(); i++) {
//if (contourArea(contours[i]) < (ivs_width*ivs_height) / 2000)
//continue;
Rect temp_rect = boundingRect(contours[i]);
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
float rect_center_x = rect_left_x + rect_width / 2.0;
float rect_center_y = rect_top_y + rect_height / 2.0;
float obj_x_max = (rect_left_x + rect_width) / temp_g_ori_yuv_width;
float obj_x_min = rect_left_x / temp_g_ori_yuv_width;
float obj_y_max = (rect_top_y + rect_height) / temp_g_ori_yuv_height;
float obj_y_min = rect_top_y / temp_g_ori_yuv_height;
if (obj_x_max <= thres_x_min ||
obj_x_min >= thres_x_max ||
obj_y_max <= thres_y_min ||
obj_y_min >= thres_y_max)
{
continue;
}
else {
if (obj_x_min < thres_x_min) {
obj_x_min = thres_x_min;
}
if (obj_x_max > thres_x_max) {
obj_x_max = thres_x_max;
}
if (obj_y_min < thres_y_min) {
obj_y_min = thres_y_min;
}
if (obj_y_max > thres_y_max) {
obj_y_max = thres_y_max;
}
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
float obj_center_x = (obj_x_min + obj_x_max) / 2.0;
float obj_width = (obj_x_max - obj_x_min);
obj_center_x = (obj_center_x - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_width = obj_width * (1.0 / cut_thres_ratio);
obj_x_min = obj_center_x - obj_width / 2.0;
obj_x_max = obj_center_x + obj_width / 2.0;
}
else {
float obj_center_y = (obj_y_min + obj_y_max) / 2.0;
float obj_height = (obj_y_max - obj_y_min);
obj_center_y = (obj_center_y - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_height = obj_height * (1.0 / cut_thres_ratio);
obj_y_min = obj_center_y - obj_height / 2.0;
obj_y_max = obj_center_y + obj_height / 2.0;
}
if (obj_x_min < 0.0)
obj_x_min = 0.0;
if (obj_x_max > 1.0)
obj_x_max = 1.0;
if (obj_y_min < 0.0)
obj_y_min = 0.0;
if (obj_y_max > 1.0)
obj_y_max = 1.0;
obj_x_min = obj_x_min * (float)i_InSourceOri_w; //1920
obj_x_max = obj_x_max * (float)i_InSourceOri_w; //1920
obj_y_min = obj_y_min * (float)i_InSourceOri_h; //1080
obj_y_max = obj_y_max * (float)i_InSourceOri_h; //1080
rect_left_x = obj_x_min;
rect_top_y = obj_y_min;
rect_width = (obj_x_max - obj_x_min);
rect_height = (obj_y_max - obj_y_min);
rect_center_x = rect_left_x + rect_width / 2.0;
rect_center_y = rect_top_y + rect_height / 2.0;
int checkisInside = 1;
if (strcmp(SystemSetting.enable_bounding_box, "No") == 0) {
checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 0);
}
if (checkisInside == 1) {
store_rect_contours.push_back(temp_rect);
store_rect_contours[contours_size] += inflationOffset;
store_rect_contours[contours_size] += inflationSize;
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
else {
store_rect_contours_not_in_zone.push_back(temp_rect);
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width += (store_rect_contours_not_in_zone[contours_size_not_in_zone].x - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].x = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height += (store_rect_contours_not_in_zone[contours_size_not_in_zone].y - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].y = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x + store_rect_contours_not_in_zone[contours_size_not_in_zone].width > ivs_width - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width = ivs_width - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].x;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y + store_rect_contours_not_in_zone[contours_size_not_in_zone].height > ivs_height - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height = ivs_height - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].y;
}
contours_size_not_in_zone++;
}
}
}
}
}
else {
if (i_InSourceOri_h >= 1 && i_InSourceOri_w >= 1) {
float temp_g_ori_yuv_height = (float)i_InSourceOri_h;
float temp_g_ori_yuv_width = (float)i_InSourceOri_w;
for (int i = 0; i < (int)contours.size(); i++) {
//if (contourArea(contours[i]) < (ivs_width*ivs_height) / 2000)
//continue;
Rect temp_rect = boundingRect(contours[i]);
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
float rect_center_x = rect_left_x + rect_width / 2.0;
float rect_center_y = rect_top_y + rect_height / 2.0;
//int checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 1);
int checkisInside = 1;
if (strcmp(SystemSetting.enable_bounding_box, "No") == 0) {
checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 0);
}
//printf("\n--------checkisInside:%d,%f,%f,%f,%f,%d,%d,%d,%d,%d,%d\n", checkisInside, rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h,
//temp_rect.x, temp_rect.y, temp_rect.width, temp_rect.height);
if (checkisInside == 1) {
store_rect_contours.push_back(temp_rect);
store_rect_contours[contours_size] += inflationOffset;
store_rect_contours[contours_size] += inflationSize;
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
else {
store_rect_contours_not_in_zone.push_back(temp_rect);
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width += (store_rect_contours_not_in_zone[contours_size_not_in_zone].x - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].x = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height += (store_rect_contours_not_in_zone[contours_size_not_in_zone].y - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].y = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x + store_rect_contours_not_in_zone[contours_size_not_in_zone].width > ivs_width - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width = ivs_width - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].x;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y + store_rect_contours_not_in_zone[contours_size_not_in_zone].height > ivs_height - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height = ivs_height - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].y;
}
contours_size_not_in_zone++;
}
}
}
}
//printf("\ndiffer image-------8\n");
//float distance_filter = 30.0;
#if 1
while ((int)store_rect_contours.size() >= 1) {
combine_rect_contours.push_back(store_rect_contours[(int)store_rect_contours.size() - 1]);
store_ivs_object.push_back(store_rect_contours[(int)store_rect_contours.size() - 1]);
store_rect_contours.pop_back();
#if 0
Rect bounding_for_a_object;
bounding_for_a_object = combine_rect_contours[(int)combine_rect_contours.size() - 1];
//int center_a_x = bounding_for_a_object.x + (bounding_for_a_object.width / 2);
//int center_a_y = bounding_for_a_object.y + (bounding_for_a_object.height / 2);
for (int i = 0; i < (int)store_rect_contours.size(); i++) {
it_store_rect_contours = store_rect_contours.begin() + i;
Rect bounding_for_b_object(it_store_rect_contours->x, it_store_rect_contours->y,
it_store_rect_contours->width, it_store_rect_contours->height);
//int center_b_x = bounding_for_b_object.x + (bounding_for_b_object.width / 2);
//int center_b_y = bounding_for_b_object.y + (bounding_for_b_object.height / 2);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
Rect bounding_for_union_object = bounding_for_a_object | bounding_for_b_object;
//printf("\n-----inter:%d,union:%d,a:%d,b:%d\n", bounding_for_intersection_object.area(), bounding_for_union_object.area(), bounding_for_a_object.area(), bounding_for_b_object.area());
//int distance_a_and_b = (int)sqrt((double)((center_a_x - center_b_x)*(center_a_x - center_b_x) + (center_a_y - center_b_y)*(center_a_y - center_b_y)));
if (bounding_for_intersection_object.area() >= 1 ||
//distance_a_and_b <= (int)distance_filter
//|| bounding_for_union_object.area() == bounding_for_a_object.area()
//|| bounding_for_union_object.area() == bounding_for_b_object.area()
//|| rect_overlap_ratio_union(bounding_for_a_object, bounding_for_b_object) > 0.0
//|| rect_overlap_ratio(bounding_for_a_object, bounding_for_b_object) > 0.0
/*||*/ rect_nms(bounding_for_a_object, bounding_for_b_object) > 0.0
) {
combine_rect_contours.pop_back();
store_ivs_object.pop_back();
store_rect_contours.erase(it_store_rect_contours);
i--;
combine_rect_contours.push_back(bounding_for_union_object);
store_ivs_object.push_back(bounding_for_union_object);
bounding_for_a_object = bounding_for_union_object;
//center_a_x = bounding_for_a_object.x + (bounding_for_a_object.width / 2);
//center_a_y = bounding_for_a_object.y + (bounding_for_a_object.height / 2);
}
}
#endif
}
#endif
//printf("\ndiffer image-------9\n");
int sum_area = 0;
for (int i = 0; i < (int)combine_rect_contours.size(); i++) {
Rect bounding_for_a_object;
bounding_for_a_object = combine_rect_contours[i];
sum_area += bounding_for_a_object.area();
double object_width = (double)bounding_for_a_object.width;
double object_height = (double)bounding_for_a_object.height;
double object_x_left = (double)bounding_for_a_object.x;
double object_y_top = (double)bounding_for_a_object.y;
double object_center_x = object_x_left + object_width / 2.0;
double object_center_y = object_y_top + object_height / 2.0;
double object_x_right = object_x_left + object_width;
double object_y_bottom = object_y_top + object_height;
if (object_width / object_height > 16.0 / 9.0) {
double temp_height = object_width * 9.0 / 16.0;
object_y_top = object_center_y - temp_height / 2.0;
object_y_bottom = object_center_y + temp_height / 2.0;
if (object_y_top < 0.0) {
temp_height = temp_height + object_y_top;
object_y_top = 0.0;
}
if (object_y_bottom > ((double)ivs_height) - 1.0) {
temp_height = temp_height - (object_y_bottom - (((double)ivs_height) - 1.0));
object_y_bottom = ((double)ivs_height) - 1.0;
}
object_center_y = (object_y_top + object_y_bottom) / 2.0;
object_height = object_y_bottom - object_y_top;
}
else if (object_width / object_height < 5.0 / 5.0) {
double temp_width = object_height * 5.0 / 5.0;
object_x_left = object_center_x - temp_width / 2.0;
object_x_right = object_center_x + temp_width / 2.0;
if (object_x_left < 0.0) {
temp_width = temp_width + object_x_left;
object_x_left = 0.0;
}
if (object_x_right > ((double)ivs_width) - 1.0) {
temp_width = temp_width - (object_x_right - (((double)ivs_width) - 1.0));
object_x_right = ((double)ivs_width) - 1.0;
}
object_center_x = (object_x_left + object_x_right) / 2.0;
object_width = object_x_right - object_x_left;
}
combine_rect_contours[i].x = (int)object_x_left;
combine_rect_contours[i].y = (int)object_y_top;
combine_rect_contours[i].width = (int)object_width;
combine_rect_contours[i].height = (int)object_height;
}
double area_scale = ((double)sum_area) / ((double)ivs_width * (double)ivs_height);
//printf("\n-----------area_scale:%lf\n", area_scale);
//printf("\ndiffer image --------------- check_if_tempering_many_times:%d\n", check_if_tempering_many_times);
//printf("\n-------tempering_ready:%d\n", tempering_ready);
//printf("\n-------switch_happened:%d\n", get_check_if_existing_any_switch_happened());
if (not_to_show_tempering == 1 || (area_scale <= 0.95 && tempering_ready == 0))
{
check_if_tempering_many_times = (temp_AI_fps - 1) * 4;
current_store_object_size = 0;
tempering_ready = 0;
if (not_to_show_tempering == 0 && (/*(last_day_or_night_mode > 0 && last_day_or_night_mode != current_day_or_night_mode)*/
/*get_check_if_existing_any_switch_happened() == 1 ||*/ *no_tempering == 1 || record_change_state == 1)) {
record_change_state = 1;
//printf("\ndiffer image --------------- 66\n");
if (check_if_compute_median_finish == 1) {
for (int i = 0; i < store_img_background_array_length; i++) {
img_background_array[i].release();
}
store_img_background_array_length = 0;
current_index_img_background_array = 0;
virtual_index_img_background_array = 0;
check_if_tempering_happened = 0;
record_change_state = 0;
*no_tempering = 0;
}
}
else
{
#if 0
if (strcmp(viewChannelData[0].enable_ivs_and_ai, "Yes") == 0) {
if (strcmp(viewChannelData[0].enable_ivs_fix_mode, "Yes") == 0) {
for (int index_zone = 0; index_zone < viewChannelData[0].count_zone; index_zone++)
{
//if (strcmp(viewDetectionZone[0][index_zone].enable_ivs_zone, "Yes") == 0)
{
float min_x_points = (float)viewDetectionZone[0][index_zone].min_x_points * (float)ivs_width / (float)CANVAS_WIDTH;
float max_x_points = (float)viewDetectionZone[0][index_zone].max_x_points * (float)ivs_width / (float)CANVAS_WIDTH;
float min_y_points = (float)viewDetectionZone[0][index_zone].min_y_points * (float)ivs_height / (float)CANVAS_HEIGHT;
float max_y_points = (float)viewDetectionZone[0][index_zone].max_y_points * (float)ivs_height / (float)CANVAS_HEIGHT;
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = 0.8 * 100;
pNext->confidence2 = 0.8 * 100;
float temp_a_x = min_x_points;
float temp_a_y = min_y_points;
float temp_a_width = max_x_points - min_x_points;
float temp_a_height = max_y_points - min_y_points;
float thres_a_width = 8.0;
float thres_a_height = 6.0;
if (temp_a_x + temp_a_width < thres_a_width) {
temp_a_x = 0;
temp_a_width = thres_a_width;
}
else if (temp_a_x >= ivs_width - thres_a_width) {
temp_a_x = ivs_width - thres_a_width - 1;
temp_a_width = thres_a_width;
}
else {
if (temp_a_width < thres_a_width) {
temp_a_x -= (thres_a_width - temp_a_width) / 2.0;
temp_a_width = thres_a_width;
}
}
if (temp_a_y + temp_a_height < thres_a_height) {
temp_a_y = 0;
temp_a_height = thres_a_height;
}
else if (temp_a_y >= ivs_height - thres_a_height) {
temp_a_y = ivs_height - thres_a_height - 1;
temp_a_height = thres_a_height;
}
else {
if (temp_a_height < thres_a_height) {
temp_a_y -= (thres_a_height - temp_a_height) / 2.0;
temp_a_height = thres_a_height;
}
}
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = temp_a_x * ratio_width;
pNext->top_y = temp_a_y * ratio_height;
pNext->width = temp_a_width * ratio_width;
pNext->height = temp_a_height * ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 2;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
else {
for (int i = 0; i < (int)combine_rect_contours.size(); i++)
{
Rect bounding_for_a_object;
bounding_for_a_object = combine_rect_contours[i];
//current_store_object,不能放在last_store_object_size裡面
current_store_object_x[current_store_object_size] = bounding_for_a_object.x;
current_store_object_y[current_store_object_size] = bounding_for_a_object.y;
current_store_object_w[current_store_object_size] = bounding_for_a_object.width;
current_store_object_h[current_store_object_size] = bounding_for_a_object.height;
current_store_object_size++;
if (last_store_object_size >= 1) {
double intersect_ratio = 0.0;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
Rect bounding_for_b_object(last_store_object_x[index_last], last_store_object_y[index_last],
last_store_object_w[index_last], last_store_object_h[index_last]);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
if (bounding_for_intersection_object.area() >= 1)
{
double temp_intersect_ratio = (double)bounding_for_intersection_object.area() / (double)bounding_for_a_object.area();
if (temp_intersect_ratio > intersect_ratio) {
intersect_ratio = temp_intersect_ratio;
}
}
}
Mat roi_a_object = masked_certain(bounding_for_a_object);
double count_non_zero = ((double)countNonZero(roi_a_object)) / ((double)bounding_for_a_object.width*(double)bounding_for_a_object.height);
roi_a_object.release();
//printf("\n---------count_non_zero:%lf\n", count_non_zero);
if (intersect_ratio >= (double)atoi(viewChannelData[0].confidence_unknown_object) / 100.0 &&
count_non_zero >= (double)atoi(viewChannelData[0].confidence2_unknown_object) / 100.0)
{
rectangle(bitwise_and_before_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(short_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(long_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
#if 0
printf("\n------------bounding_for_a_object.x:%d,bounding_for_a_object.y:%d\n", bounding_for_a_object.x, bounding_for_a_object.y);
#endif
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = intersect_ratio * 100;
pNext->confidence2 = count_non_zero * 100;
float temp_a_x = (float)(bounding_for_a_object.x);
float temp_a_y = (float)(bounding_for_a_object.y);
float temp_a_width = (float)(bounding_for_a_object.width);
float temp_a_height = (float)(bounding_for_a_object.height);
float thres_a_width = 8.0;
float thres_a_height = 6.0;
if (temp_a_x + temp_a_width < thres_a_width) {
temp_a_x = 0;
temp_a_width = thres_a_width;
}
else if (temp_a_x >= ivs_width - thres_a_width) {
temp_a_x = ivs_width - thres_a_width - 1;
temp_a_width = thres_a_width;
}
else {
if (temp_a_width < thres_a_width) {
temp_a_x -= (thres_a_width - temp_a_width) / 2.0;
temp_a_width = thres_a_width;
}
}
if (temp_a_y + temp_a_height < thres_a_height) {
temp_a_y = 0;
temp_a_height = thres_a_height;
}
else if (temp_a_y >= ivs_height - thres_a_height) {
temp_a_y = ivs_height - thres_a_height - 1;
temp_a_height = thres_a_height;
}
else {
if (temp_a_height < thres_a_height) {
temp_a_y -= (thres_a_height - temp_a_height) / 2.0;
temp_a_height = thres_a_height;
}
}
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = temp_a_x * ratio_width;
pNext->top_y = temp_a_y * ratio_height;
pNext->width = temp_a_width * ratio_width;
pNext->height = temp_a_height * ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 2;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
}
}
#endif
#if 0
for (int i = 0; i < (int)store_rect_contours_not_in_zone.size(); i++) {
Rect bounding_for_a_object;
bounding_for_a_object = store_rect_contours_not_in_zone[i];
if (//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) >= (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) > (double)atoi(viewChannelData[0].obj_max_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) < (double)atoi(viewChannelData[0].obj_min_proportion) / 100.0
//strcmp(viewChannelData[0].enable_show_unknown_object, "No") == 0
)
{
continue;
}
//current_store_object,不能放在last_store_object_size裡面
current_store_object_x[current_store_object_size] = bounding_for_a_object.x;
current_store_object_y[current_store_object_size] = bounding_for_a_object.y;
current_store_object_w[current_store_object_size] = bounding_for_a_object.width;
current_store_object_h[current_store_object_size] = bounding_for_a_object.height;
current_store_object_size++;
if (last_store_object_size >= 1) {
double intersect_ratio = 0.0;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
Rect bounding_for_b_object(last_store_object_x[index_last], last_store_object_y[index_last],
last_store_object_w[index_last], last_store_object_h[index_last]);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
if (bounding_for_intersection_object.area() >= 1)
{
double temp_intersect_ratio = (double)bounding_for_intersection_object.area() / (double)bounding_for_a_object.area();
if (temp_intersect_ratio > intersect_ratio) {
intersect_ratio = temp_intersect_ratio;
}
}
}
Mat roi_a_object = masked_certain(bounding_for_a_object);
double count_non_zero = ((double)countNonZero(roi_a_object)) / ((double)bounding_for_a_object.width*(double)bounding_for_a_object.height);
roi_a_object.release();
//printf("\n---------count_non_zero:%lf\n", count_non_zero);
if (intersect_ratio >= (double)atoi(viewChannelData[0].confidence_unknown_object) / 100.0 &&
count_non_zero >= (double)atoi(viewChannelData[0].confidence2_unknown_object) / 100.0) {
rectangle(bitwise_and_before_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(short_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(long_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
#if 0
printf("\n------------bounding_for_a_object.x:%d,bounding_for_a_object.y:%d\n", bounding_for_a_object.x, bounding_for_a_object.y);
#endif
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = intersect_ratio * 100;
pNext->confidence2 = count_non_zero * 100;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = ((float)(bounding_for_a_object.x))*ratio_width;
pNext->top_y = ((float)(bounding_for_a_object.y))*ratio_height;
pNext->width = ((float)(bounding_for_a_object.width))*ratio_width;
pNext->height = ((float)(bounding_for_a_object.height))*ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
#endif
#if 1
for (int i = 0; i < (int)store_ivs_object.size() /*&& area_scale <= 0.45*/; i++) {
Rect bounding_for_a_object;
bounding_for_a_object = store_ivs_object[i];
if (//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) >= (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) > (double)atoi(viewChannelData[0].obj_max_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) < (double)atoi(viewChannelData[0].obj_min_proportion) / 100.0
//strcmp(viewChannelData[0].enable_show_unknown_object, "No") == 0
)
{
continue;
}
//current_store_object,不能放在last_store_object_size裡面
current_store_object_x[current_store_object_size] = bounding_for_a_object.x;
current_store_object_y[current_store_object_size] = bounding_for_a_object.y;
current_store_object_w[current_store_object_size] = bounding_for_a_object.width;
current_store_object_h[current_store_object_size] = bounding_for_a_object.height;
current_store_object_size++;
if (last_store_object_size >= 1) {
double intersect_ratio = 0.0;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
Rect bounding_for_b_object(last_store_object_x[index_last], last_store_object_y[index_last],
last_store_object_w[index_last], last_store_object_h[index_last]);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
if (bounding_for_intersection_object.area() >= 1)
{
double temp_intersect_ratio = (double)bounding_for_intersection_object.area() / (double)bounding_for_a_object.area();
if (temp_intersect_ratio > intersect_ratio) {
intersect_ratio = temp_intersect_ratio;
}
}
}
Mat roi_a_object = masked_certain(bounding_for_a_object);
double count_non_zero = ((double)countNonZero(roi_a_object)) / ((double)bounding_for_a_object.width*(double)bounding_for_a_object.height);
roi_a_object.release();
//printf("\n---------count_non_zero:%lf\n", count_non_zero);
if (intersect_ratio >= (double)atoi(viewChannelData[0].confidence_unknown_object) / 100.0 &&
count_non_zero >= (double)atoi(viewChannelData[0].confidence2_unknown_object) / 100.0) {
rectangle(bitwise_and_before_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(short_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
rectangle(long_term_contours,
bounding_for_a_object,
Scalar(255, 255, 255),
3, 8, 0);
#if 0
printf("\n------------bounding_for_a_object.x:%d,bounding_for_a_object.y:%d\n", bounding_for_a_object.x, bounding_for_a_object.y);
#endif
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = intersect_ratio * 100;
pNext->confidence2 = count_non_zero * 100;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = ((float)(bounding_for_a_object.x))*ratio_width;
pNext->top_y = ((float)(bounding_for_a_object.y))*ratio_height;
pNext->width = ((float)(bounding_for_a_object.width))*ratio_width;
pNext->height = ((float)(bounding_for_a_object.height))*ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
#endif
last_store_object_size = current_store_object_size;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
last_store_object_x[index_last] = current_store_object_x[index_last];
last_store_object_y[index_last] = current_store_object_y[index_last];
last_store_object_w[index_last] = current_store_object_w[index_last];
last_store_object_h[index_last] = current_store_object_h[index_last];
}
}
}
else if (not_to_show_tempering == 0 && ((area_scale >= 0.95 && check_if_tempering_many_times <= 0) || tempering_ready == 1))//(area_scale >= 0.83 && imageDnData.check_if_switch_happened[MAX_SIZE_SWITCH_HAPPENED - 1] == 1) ||
{
current_store_object_size = 0;
last_store_object_size = current_store_object_size;
tempering_ready = 1;
if (check_if_compute_median_finish == 1) {
//printf("\ndiffer image --------------- 3\n");
for (int i = 0; i < store_img_background_array_length; i++) {
img_background_array[i].release();
}
store_img_background_array_length = 0;
current_index_img_background_array = 0;
virtual_index_img_background_array = 0;
check_if_tempering_happened = (temp_AI_fps - 1) * 2;
record_change_state = 0;
*no_tempering = 0;
tempering_ready = 0;
}
}
#if 0
else if ((area_scale < 0.83 && get_check_if_existing_any_switch_happened() == 1) ||
record_change_state == 1) {
current_store_object_size = 0;
last_store_object_size = current_store_object_size;
record_change_state = 1;
//printf("\ndiffer image --------------- 6\n");
if (check_if_compute_median_finish == 1) {
for (int i = 0; i < store_img_background_array_length; i++) {
img_background_array[i].release();
}
store_img_background_array_length = 0;
current_index_img_background_array = 0;
virtual_index_img_background_array = 0;
check_if_tempering_happened = 0;
record_change_state = 0;
*no_tempering = 0;
tempering_ready = 0;
}
}
#endif
else if (not_to_show_tempering == 0 && (area_scale >= 0.95 && check_if_tempering_many_times >= 1)) {
current_store_object_size = 0;
last_store_object_size = current_store_object_size;
/*
printf("\ndiffer image --------------- 4\n");
printf("\n------------last_day_or_night_mode:%d\n", last_day_or_night_mode);
printf("\n------------current_day_or_night_mode:%d\n", current_day_or_night_mode);
printf("\n------------no_tempering:%d\n", *no_tempering);
printf("\n------------record_change_state:%d\n", record_change_state);*/
if (/*last_day_or_night_mode > 0 && last_day_or_night_mode == current_day_or_night_mode */
/*get_check_if_existing_any_switch_happened() == 0 &&*/ *no_tempering == 0 && record_change_state == 0) {
//printf("\ndiffer image --------------- 5\n");
check_if_tempering_many_times--;
}
else if (/*(last_day_or_night_mode > 0 && last_day_or_night_mode != current_day_or_night_mode) */
/*imageDnData.check_if_switch_happened[MAX_SIZE_SWITCH_HAPPENED - 1] == 1 ||*/ *no_tempering == 1 || record_change_state == 1 /*||
get_check_if_existing_any_switch_happened() == 1*/) {
record_change_state = 1;
//printf("\ndiffer image --------------- 6\n");
if (check_if_compute_median_finish == 1) {
for (int i = 0; i < store_img_background_array_length; i++) {
img_background_array[i].release();
}
store_img_background_array_length = 0;
current_index_img_background_array = 0;
virtual_index_img_background_array = 0;
check_if_tempering_happened = 0;
record_change_state = 0;
*no_tempering = 0;
tempering_ready = 0;
}
}
}
for (int i = 0; i < (int)contours.size(); i++) {
contours[i].clear();
vector<Point>().swap(contours[i]);
}
contours.clear();
vector<vector<Point>>().swap(contours);
store_rect_contours.clear();
vector<Rect>().swap(store_rect_contours);
store_ivs_object.clear();
vector<Rect>().swap(store_ivs_object);
store_rect_contours_not_in_zone.clear();
vector<Rect>().swap(store_rect_contours_not_in_zone);
combine_rect_contours.clear();
vector<Rect>().swap(combine_rect_contours);
//printf("\ndiffer image-------10\n");
//////////////////將最後結果mat encode轉換成char *送到網頁
if (*image_size == 0) {
if (draw_img_long == 1 && draw_img_short == 0) {
vector<uchar> data_encode;
imencode(".jpeg", long_term_contours, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
else if (draw_img_long == 0 && draw_img_short == 1) {
vector<uchar> data_encode;
imencode(".jpeg", short_term_contours, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
else {
vector<uchar> data_encode;
imencode(".jpeg", bitwise_and_before_contours, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
}
//printf("\ndiffer image-------11\n");//
short_term_contours.release();
long_term_contours.release();
bitwise_and_before_contours.release();
//////////////////釋放記憶體
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
//printf("\ndiffer image-------12\n");
if (!img_blur_short_term.empty())
img_blur_short_term.release();
if (!img_blur_long_term.empty())
img_blur_long_term.release();
img_yuv.release();
img_blur_yuv.release();
masked_certain.release();
//printf("\ndiffer_image--------------------end\n");
return (int)valid_bbox_idx;
//return length;
}
}
}
}
//int count_mog2 = 0;
int mog2_image(char *output_image, int* image_size, char * snaphd_image_buffer, int snaphd_image_size, detection_pos* PosInfo, int i_InSourceOri_w, int i_InSourceOri_h, int draw_img_long, int draw_img_short, int* no_tempering, int not_to_show_tempering) // For normal type
{
if (AI_fps <= 0 || strcmp(viewChannelData[0].enable_unknown_object, "No") == 0 || check_if_compute_median_finish == 0) {
return 0;
}
else {
//printf("\ndiffer_image--------------------start-----1\n");
detection_pos* pNext = NULL;
int temp_AI_fps = AI_fps >= 2 ? AI_fps : 2;
if (check_if_tempering_many_times == -100) {
check_if_tempering_many_times = (temp_AI_fps - 1) * 2;
}
uint32_t valid_bbox_idx = 0;
int ivs_width = 240;//320
int ivs_height = 135;//180
float ratio_width = (float)i_InSourceOri_w / (float)ivs_width;
float ratio_height = (float)i_InSourceOri_h / (float)ivs_height;
if (not_to_show_tempering == 0 && check_if_tempering_happened <= 0) {
*no_tempering = 0;
check_if_tempering_many_times = (temp_AI_fps - 1) * 2;
g_progress_bar = 100.0;
}
else if (not_to_show_tempering == 0 && check_if_tempering_happened >= 1) {
g_progress_bar = 1.0;
if (PosInfo != NULL && not_to_show_tempering == 0) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "tampering");
pNext->confidence = (float)sqrt((double)1.0 * (double)100)*10.0;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = (float)ivs_width * ratio_width * (float)0.35;
pNext->top_y = (float)ivs_height * ratio_height * (float)0.35;
pNext->width = (float)ivs_width * ratio_width * (float)0.3;
pNext->height = (float)ivs_height * ratio_height * (float)0.3;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
if (check_if_tempering_happened == 1){
g_multiLayerMOG2.clearMemory();
g_multiLayerMOG2.initialize();
g_count_mog2 = 0;
g_multiLayerMOG2_2.clearMemory();
g_multiLayerMOG2_2.initialize();
g_count_mog2_2 = 0;
}
check_if_tempering_happened--;
return (int)valid_bbox_idx;
}
g_progress_bar = 0.0;
double learning_rate = 1.0 / ((double)temp_AI_fps * 120.0);
double temp_time_interval_with_msec = (double)atoi(viewChannelData[0].dwell_unknown_object) / ((double)MAX_SHORT_TERM - 1.0)*1000.0; //TIME_INTERVAL_WITH_MSEC
//printf("\n------temp_time_interval_with_msec:%lf\n", temp_time_interval_with_msec);
//printf("\nTTTTTTTTT no_tempering:%d\n", *no_tempering);
time_t current_time = time(0);
pop_not_to_record_hash(current_time);
//printf("\nTTTTTTTTTT i_InSourceOri_w:%d , i_InSourceOri_h:%d\n", i_InSourceOri_w, i_InSourceOri_h);
//printf("\ndiffer image-------1\n");
current_ms_differ_image = getCurrentTime();
//printf("\n-------------%ld\n", current_ms_differ_image);
//printf("\nTTTTTTTTTT ratio_width:%f , ratio_height:%f\n", ratio_width, ratio_height);
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_gray;
Mat img_blur;
Mat img_blur_hash;
Mat img_thres;
//Mat img_morph_open_one;
//Mat img_morph_open_twice;
//Mat img_morph_close_one;
//Mat img_morph_close_twice;
Mat img_absdiff;
//Mat bitwise_and_before_contours;
//Mat short_term_contours;
//Mat long_term_contours;
//vector<Mat> img_channels;
//Mat img_absdiff_short_term;
//Mat img_blur_short_term;
//Mat img_absdiff_long_term;
//Mat img_blur_long_term;
//Mat img_yuv;
//Mat img_blur_yuv;
//Mat masked_certain;
//int thres_light[3] = { 0 };//25
//printf("\ndiffer image-------2\n");
////////////將原本要送到網頁char * decode成mat
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
Mat temp_img_decode;
temp_img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\n-----%d,%d,%d,%d\n", temp_img_decode.size().width, i_InSourceOri_w, temp_img_decode.size().height, i_InSourceOri_h);
if (temp_img_decode.size().width != VIEW_WEB_WIDTH_HD || temp_img_decode.size().height != VIEW_WEB_HEIGHT_HD /*|| g_pMOG2 == nullptr || g_pMOG2_2 == nullptr*/)
{
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
temp_img_decode.release();
return 0;
}
else
{
Mat img_decode;
resize(temp_img_decode, img_decode, Size(ivs_width, ivs_height), INTER_NEAREST);
temp_img_decode.release();
/////////////從此開始為opencv基本影像計算
//printf("\ndiffer_image--------------------start-----1-------1\n");
//灰階化
cvtColor(img_decode, img_gray, CV_BGR2GRAY);
//printf("\ndiffer_image--------------------start-----1-------2\n");
#if 1
//過濾時間banner
{
int mask_width = ivs_width;
int mask_height = ivs_height;
Mat imageMask(mask_height, mask_width, CV_8UC3, Scalar(0, 0, 0));
if (strcmp(heartbeatData.events_default_version, "4") == 0) {
imageMask(Rect(6, 10, mask_width - 12, mask_height - 20)) = Scalar(255, 255, 255); //make rectangle 1
}
else {
imageMask(Rect(6, 10, mask_width - 12, mask_height - 20)) = Scalar(255, 255, 255); //make rectangle 1
}
Mat imageMask_gray;
cvtColor(imageMask, imageMask_gray, CV_BGR2GRAY);
imageMask.release();
Mat maskedImage;
bitwise_and(img_gray, imageMask_gray, maskedImage);
imageMask_gray.release();
img_gray.release();
img_gray = maskedImage.clone();
maskedImage.release();
}
#endif
//printf("\ndiffer_image--------------------start-----1-------3\n");
//split(img_decode, img_channels);
//Mat abs_r_g = abs(img_channels[2] - img_channels[1]);
//Mat abs_r_b = abs(img_channels[2] - img_channels[0]);
//Mat abs_g_b = abs(img_channels[1] - img_channels[0]);
//double r_g = countNonZero(abs_r_g);
//double r_b = countNonZero(abs_r_b);
//double g_b = countNonZero(abs_g_b);
//abs_r_g.release();
//abs_r_b.release();
//abs_g_b.release();
//img_channels[0].release();
//img_channels[1].release();
//img_channels[2].release();
//img_channels.clear();
//vector<Mat>().swap(img_channels);
//double ratio_determine_if_color = (r_g + r_b + g_b) / ((double)ivs_width*(double)ivs_height);
//printf("\n-------imageDnData.current_day_or_night_mode:%d\n", imageDnData.current_day_or_night_mode);
//printf("\n-------imageDnData.check_if_switch_happene[0]:%d\n", imageDnData.check_if_switch_happened[0]);
//printf("\ndiffer_image--------------------start-----1-------4\n");
//if (not_to_show_tempering == 0) {
//if (imageDnData.current_day_or_night_mode == 1) {
//printf("\nimage is color:%lf\n", ratio_determine_if_color);
//last_day_or_night_mode = current_day_or_night_mode;
//current_day_or_night_mode = 1;
//}
//else {
//printf("\nimage is grayscale:%lf\n", ratio_determine_if_color);
//last_day_or_night_mode = current_day_or_night_mode;
//current_day_or_night_mode = 2;
//}
//}
//thres_light[0] = 6;//80 //8
//thres_light[1] = 0;//25 //3
//thres_light[2] = 0;//25 //3
//if (strcmp(viewChannelData[0].ivs_mode, "0") == 0) {
//thres_light[0] = 6;//80 //8
//}
//else if (strcmp(viewChannelData[0].ivs_mode, "1") == 0) {
//thres_light[0] = 4;//80 //8
//}
//else if (strcmp(viewChannelData[0].ivs_mode, "2") == 0) {
//thres_light[0] = 2;//80 //8
//}
//模糊化
img_blur = img_gray.clone();
blur(img_gray, img_blur_hash, Size(3, 3));//5 5 //BLUR_SIZE
//bilateralFilter(img_gray, img_blur, 5, 75, 75);
//GaussianBlur(img_gray, img_blur_hash, Size(3, 3),0,0);//4 4 3 3
img_gray.release();
//printf("\ndiffer_image--------------------start-----1-------5\n");
if (img_blur.size().width == 0 || img_blur.size().height == 0) {
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
img_blur.release();
img_blur_hash.release();
return 0;
}
else
{
g_progress_bar = 0.0;
Mat img_absdiff;
#if 1
if (g_count_mog2 >= 250 && g_count_mog2_2 >= 250) {
//int history = 500; // 記憶歷史幀數
//double varThreshold = 20; // 變異閾值
//bool detectShadows = false; // 是否檢測陰影
if (g_count_mog2 >= g_count_mog2_2) {
//g_pMOG2.release();
//g_pMOG2 = createBackgroundSubtractorMOG2(history, varThreshold, detectShadows);
g_multiLayerMOG2.clearMemory();
g_multiLayerMOG2.initialize();
g_count_mog2 = 0;
}
else {
//g_pMOG2_2.release();
//g_pMOG2_2 = createBackgroundSubtractorMOG2(history, varThreshold, detectShadows);
g_multiLayerMOG2_2.clearMemory();
g_multiLayerMOG2_2.initialize();
g_count_mog2_2 = 0;
}
}
if (g_count_mog2 >= g_count_mog2_2) {
//g_pMOG2_2->apply(img_blur, img_absdiff, learning_rate);// 應用MOG2進行背景減除,並設置學習率為0.01
g_multiLayerMOG2_2.processFrame(img_blur, img_absdiff, learning_rate);
g_count_mog2_2++;
img_absdiff.release();
//g_pMOG2->apply(img_blur, img_absdiff, learning_rate);// 應用MOG2進行背景減除,並設置學習率為0.01
g_multiLayerMOG2.processFrame(img_blur, img_absdiff, learning_rate);
g_count_mog2++;
}
else {
//g_pMOG2->apply(img_blur, img_absdiff, learning_rate);// 應用MOG2進行背景減除,並設置學習率為0.01
g_multiLayerMOG2.processFrame(img_blur, img_absdiff, learning_rate);
g_count_mog2++;
img_absdiff.release();
//g_pMOG2_2->apply(img_blur, img_absdiff, learning_rate);// 應用MOG2進行背景減除,並設置學習率為0.01
g_multiLayerMOG2_2.processFrame(img_blur, img_absdiff, learning_rate);
g_count_mog2_2++;
}
#endif
vector<vector<Point>> contours;
vector<Rect> store_rect_contours;
vector<Rect> combine_rect_contours;
//vector<Rect>::iterator it_store_rect_contours;
vector<Rect> store_rect_contours_not_in_zone;
vector<Rect> store_ivs_object;
//二值化 THRESH_OTSU會自動找最佳閥值
double thresh = 50;//25 //100 //50
int maxVal = 255;
//double new_threshold = 0;
/*new_threshold =*/
threshold(img_absdiff, img_thres, thresh, maxVal, THRESH_BINARY);////THRESH_OTSU THRESH_BINARY //THRESH_BINARY | THRESH_OTSU
Mat morph_matrix = getStructuringElement(MORPH_RECT, Size(2, 2));//3 3
Mat dilate_img/*, dilate_img_2*/;
dilate(img_thres, dilate_img, morph_matrix);//CV_MOP_OPEN
//morphologyEx(img_thres, dilate_img, CV_MOP_OPEN, morph_matrix);//CV_MOP_OPEN
//dilate(dilate_img, dilate_img_2, morph_matrix);
morph_matrix.release();
img_absdiff.release();
img_thres.release();
findContours(dilate_img, contours, noArray(), RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Size inflationSize(2, 2);
Point inflationOffset(-1, -1);
//dilate_img_2.release();
int contours_size = 0;
int contours_size_not_in_zone = 0;
if (g_check_if_OK_thermal == 0 && g_IsPTZDevice == 1 && strcmp(SystemSetting.enable_crop_mode, "Yes") == 0) {
if (i_InSourceOri_h >= 1 && i_InSourceOri_w >= 1 && g_framesize_height >= 1 && g_framesize_width >= 1) {
float temp_framsize_height = (float)g_framesize_height;
float temp_framsize_width = (float)g_framesize_width;
float temp_g_ori_yuv_height = (float)i_InSourceOri_h;
float temp_g_ori_yuv_width = (float)i_InSourceOri_w;
float ratio_height_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_height / temp_framsize_height;
float ratio_width_g_ori_yuv_to_ai_webpage = temp_g_ori_yuv_width / temp_framsize_width;
float thres_x_min = 0.0;
float thres_x_max = 1.0;
float thres_y_min = 0.0;
float thres_y_max = 1.0;
float cut_thres_ratio = 0.0;
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_height * temp_framsize_width) / (temp_framsize_height*temp_g_ori_yuv_width);
thres_x_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_x_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
else if (ratio_width_g_ori_yuv_to_ai_webpage < ratio_height_g_ori_yuv_to_ai_webpage) {
cut_thres_ratio = (temp_g_ori_yuv_width * temp_framsize_height) / (temp_framsize_width*temp_g_ori_yuv_height);
thres_y_min += ((1.0 - cut_thres_ratio) / 2.0);
thres_y_max -= ((1.0 - cut_thres_ratio) / 2.0);
}
for (int i = 0; i < (int)contours.size(); i++) {
//if (contourArea(contours[i]) < (ivs_width*ivs_height) / 2000)
//continue;
Rect temp_rect = boundingRect(contours[i]);
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
float rect_center_x = rect_left_x + rect_width / 2.0;
float rect_center_y = rect_top_y + rect_height / 2.0;
float obj_x_max = (rect_left_x + rect_width) / temp_g_ori_yuv_width;
float obj_x_min = rect_left_x / temp_g_ori_yuv_width;
float obj_y_max = (rect_top_y + rect_height) / temp_g_ori_yuv_height;
float obj_y_min = rect_top_y / temp_g_ori_yuv_height;
if (obj_x_max <= thres_x_min ||
obj_x_min >= thres_x_max ||
obj_y_max <= thres_y_min ||
obj_y_min >= thres_y_max)
{
continue;
}
else {
if (obj_x_min < thres_x_min) {
obj_x_min = thres_x_min;
}
if (obj_x_max > thres_x_max) {
obj_x_max = thres_x_max;
}
if (obj_y_min < thres_y_min) {
obj_y_min = thres_y_min;
}
if (obj_y_max > thres_y_max) {
obj_y_max = thres_y_max;
}
if (ratio_width_g_ori_yuv_to_ai_webpage > ratio_height_g_ori_yuv_to_ai_webpage) {
float obj_center_x = (obj_x_min + obj_x_max) / 2.0;
float obj_width = (obj_x_max - obj_x_min);
obj_center_x = (obj_center_x - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_width = obj_width * (1.0 / cut_thres_ratio);
obj_x_min = obj_center_x - obj_width / 2.0;
obj_x_max = obj_center_x + obj_width / 2.0;
}
else {
float obj_center_y = (obj_y_min + obj_y_max) / 2.0;
float obj_height = (obj_y_max - obj_y_min);
obj_center_y = (obj_center_y - 0.5) * (1.0 / cut_thres_ratio) + 0.5;
obj_height = obj_height * (1.0 / cut_thres_ratio);
obj_y_min = obj_center_y - obj_height / 2.0;
obj_y_max = obj_center_y + obj_height / 2.0;
}
if (obj_x_min < 0.0)
obj_x_min = 0.0;
if (obj_x_max > 1.0)
obj_x_max = 1.0;
if (obj_y_min < 0.0)
obj_y_min = 0.0;
if (obj_y_max > 1.0)
obj_y_max = 1.0;
obj_x_min = obj_x_min * (float)i_InSourceOri_w; //1920
obj_x_max = obj_x_max * (float)i_InSourceOri_w; //1920
obj_y_min = obj_y_min * (float)i_InSourceOri_h; //1080
obj_y_max = obj_y_max * (float)i_InSourceOri_h; //1080
rect_left_x = obj_x_min;
rect_top_y = obj_y_min;
rect_width = (obj_x_max - obj_x_min);
rect_height = (obj_y_max - obj_y_min);
rect_center_x = rect_left_x + rect_width / 2.0;
rect_center_y = rect_top_y + rect_height / 2.0;
//int checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 1);
int checkisInside = 1;
if (strcmp(SystemSetting.enable_bounding_box, "No") == 0) {
checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 0);
}
if (checkisInside == 1) {
store_rect_contours.push_back(temp_rect);
store_rect_contours[contours_size] += inflationOffset;
store_rect_contours[contours_size] += inflationSize;
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
else {
store_rect_contours_not_in_zone.push_back(temp_rect);
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width += (store_rect_contours_not_in_zone[contours_size_not_in_zone].x - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].x = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height += (store_rect_contours_not_in_zone[contours_size_not_in_zone].y - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].y = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x + store_rect_contours_not_in_zone[contours_size_not_in_zone].width > ivs_width - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width = ivs_width - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].x;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y + store_rect_contours_not_in_zone[contours_size_not_in_zone].height > ivs_height - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height = ivs_height - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].y;
}
contours_size_not_in_zone++;
}
}
}
}
}
else {
if (i_InSourceOri_h >= 1 && i_InSourceOri_w >= 1) {
float temp_g_ori_yuv_height = (float)i_InSourceOri_h;
float temp_g_ori_yuv_width = (float)i_InSourceOri_w;
for (int i = 0; i < (int)contours.size(); i++) {
//if (contourArea(contours[i]) < (ivs_width*ivs_height) / 2000)
//continue;
Rect temp_rect = boundingRect(contours[i]);
float rect_left_x = ((float)(temp_rect.x))*ratio_width;
float rect_top_y = ((float)(temp_rect.y))*ratio_height;
float rect_width = ((float)(temp_rect.width))*ratio_width;
float rect_height = ((float)(temp_rect.height))*ratio_height;
if (rect_left_x < 0) {
rect_width += (rect_left_x - 1);
rect_left_x = 0;
}
if (rect_top_y < 0) {
rect_height += (rect_top_y - 1);
rect_top_y = 0;
}
if (rect_left_x + rect_width > temp_g_ori_yuv_width - 1) {
rect_width = temp_g_ori_yuv_width - 1 - rect_left_x;
}
if (rect_top_y + rect_height > temp_g_ori_yuv_height - 1) {
rect_height = temp_g_ori_yuv_height - 1 - rect_top_y;
}
float rect_center_x = rect_left_x + rect_width / 2.0;
float rect_center_y = rect_top_y + rect_height / 2.0;
//int checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 1);
int checkisInside = 1;
if (strcmp(SystemSetting.enable_bounding_box, "No") == 0) {
checkisInside = check_if_object_in_ivs_zone(rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h, 0);
}
//printf("\n--------checkisInside:%d,%f,%f,%f,%f,%d,%d,%d,%d,%d,%d\n", checkisInside, rect_center_x, rect_center_y, rect_width, rect_height, i_InSourceOri_w, i_InSourceOri_h,
//temp_rect.x, temp_rect.y, temp_rect.width, temp_rect.height);
if (checkisInside == 1) {
store_rect_contours.push_back(temp_rect);
store_rect_contours[contours_size] += inflationOffset;
store_rect_contours[contours_size] += inflationSize;
if (store_rect_contours[contours_size].x < 0) {
store_rect_contours[contours_size].width += (store_rect_contours[contours_size].x - 1);
store_rect_contours[contours_size].x = 0;
}
if (store_rect_contours[contours_size].y < 0) {
store_rect_contours[contours_size].height += (store_rect_contours[contours_size].y - 1);
store_rect_contours[contours_size].y = 0;
}
if (store_rect_contours[contours_size].x + store_rect_contours[contours_size].width > ivs_width - 1) {
store_rect_contours[contours_size].width = ivs_width - 1 - store_rect_contours[contours_size].x;
}
if (store_rect_contours[contours_size].y + store_rect_contours[contours_size].height > ivs_height - 1) {
store_rect_contours[contours_size].height = ivs_height - 1 - store_rect_contours[contours_size].y;
}
contours_size++;
}
else {
store_rect_contours_not_in_zone.push_back(temp_rect);
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width += (store_rect_contours_not_in_zone[contours_size_not_in_zone].x - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].x = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y < 0) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height += (store_rect_contours_not_in_zone[contours_size_not_in_zone].y - 1);
store_rect_contours_not_in_zone[contours_size_not_in_zone].y = 0;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].x + store_rect_contours_not_in_zone[contours_size_not_in_zone].width > ivs_width - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].width = ivs_width - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].x;
}
if (store_rect_contours_not_in_zone[contours_size_not_in_zone].y + store_rect_contours_not_in_zone[contours_size_not_in_zone].height > ivs_height - 1) {
store_rect_contours_not_in_zone[contours_size_not_in_zone].height = ivs_height - 1 - store_rect_contours_not_in_zone[contours_size_not_in_zone].y;
}
contours_size_not_in_zone++;
}
}
}
}
#if 1
while ((int)store_rect_contours.size() >= 1) {
combine_rect_contours.push_back(store_rect_contours[(int)store_rect_contours.size() - 1]);
store_ivs_object.push_back(store_rect_contours[(int)store_rect_contours.size() - 1]);
store_rect_contours.pop_back();
}
#endif
for (int i = 0; i < (int)g_ivs_hash_record.size(); i++) {
double unseenDuration = difftime(current_time, g_ivs_hash_record[i].firstSeen);
if (unseenDuration > 5.0)
{
Mat a_object_hash_value = generateChecksumUsingHash(img_blur_hash, g_ivs_hash_record[i].bbox);
if (check_if_ivs_hash_has_been_recorded(a_object_hash_value)) {
for (int j = store_ivs_object.size() - 1; j >= 0; --j) {
Rect intersection = store_ivs_object[j] & g_ivs_hash_record[i].bbox;
if (intersection.width * intersection.height) {
store_ivs_object.erase(store_ivs_object.begin() + j); // 刪除符合條件的車輛
}
}
if (store_ivs_object.empty()) {
store_ivs_object.clear(); // 清除所有元素
store_ivs_object.shrink_to_fit(); // 釋放未使用的記憶體
}
store_ivs_object.push_back(g_ivs_hash_record[i].bbox);
}
a_object_hash_value.release();
}
}
int sum_area = 0;
for (int i = 0; i < (int)combine_rect_contours.size(); i++) {
Rect bounding_for_a_object;
bounding_for_a_object = combine_rect_contours[i];
sum_area += bounding_for_a_object.area();
double object_width = (double)bounding_for_a_object.width;
double object_height = (double)bounding_for_a_object.height;
double object_x_left = (double)bounding_for_a_object.x;
double object_y_top = (double)bounding_for_a_object.y;
double object_center_x = object_x_left + object_width / 2.0;
double object_center_y = object_y_top + object_height / 2.0;
double object_x_right = object_x_left + object_width;
double object_y_bottom = object_y_top + object_height;
if (object_width / object_height > 16.0 / 9.0) {
double temp_height = object_width * 9.0 / 16.0;
object_y_top = object_center_y - temp_height / 2.0;
object_y_bottom = object_center_y + temp_height / 2.0;
if (object_y_top < 0.0) {
temp_height = temp_height + object_y_top;
object_y_top = 0.0;
}
if (object_y_bottom > ((double)ivs_height) - 1.0) {
temp_height = temp_height - (object_y_bottom - (((double)ivs_height) - 1.0));
object_y_bottom = ((double)ivs_height) - 1.0;
}
object_center_y = (object_y_top + object_y_bottom) / 2.0;
object_height = object_y_bottom - object_y_top;
}
else if (object_width / object_height < 5.0 / 5.0) {
double temp_width = object_height * 5.0 / 5.0;
object_x_left = object_center_x - temp_width / 2.0;
object_x_right = object_center_x + temp_width / 2.0;
if (object_x_left < 0.0) {
temp_width = temp_width + object_x_left;
object_x_left = 0.0;
}
if (object_x_right > ((double)ivs_width) - 1.0) {
temp_width = temp_width - (object_x_right - (((double)ivs_width) - 1.0));
object_x_right = ((double)ivs_width) - 1.0;
}
object_center_x = (object_x_left + object_x_right) / 2.0;
object_width = object_x_right - object_x_left;
}
combine_rect_contours[i].x = (int)object_x_left;
combine_rect_contours[i].y = (int)object_y_top;
combine_rect_contours[i].width = (int)object_width;
combine_rect_contours[i].height = (int)object_height;
}
int image_center_x = ivs_width / 2;
int image_center_y = ivs_height / 2;
// 使用 std::sort 對 store_ivs_object 進行排序,基於離圖像中心點的距離
sort(store_ivs_object.begin(), store_ivs_object.end(),
[image_center_x, image_center_y](const Rect& a, const Rect& b) {
// 計算矩形 a 的中心點
int center_a_x = a.x + a.width / 2;
int center_a_y = a.y + a.height / 2;
// 計算矩形 b 的中心點
int center_b_x = b.x + b.width / 2;
int center_b_y = b.y + b.height / 2;
// 計算矩形 a 與圖像中心點的距離
double distance_a = sqrt(pow(center_a_x - image_center_x, 2) + pow(center_a_y - image_center_y, 2));
// 計算矩形 b 與圖像中心點的距離
double distance_b = sqrt(pow(center_b_x - image_center_x, 2) + pow(center_b_y - image_center_y, 2));
// 距離小的優先
return distance_a < distance_b;
});
double area_scale = ((double)sum_area) / ((double)ivs_width * (double)ivs_height);
//printf("\n-------area scale:%lf\n", area_scale);
if (not_to_show_tempering == 1 || (area_scale <= 0.95 && tempering_ready == 0))
{
check_if_tempering_many_times = (temp_AI_fps - 1) * 2;
current_store_object_size = 0;
tempering_ready = 0;
if (not_to_show_tempering == 0 && (/*(last_day_or_night_mode > 0 && last_day_or_night_mode != current_day_or_night_mode)*/
/*get_check_if_existing_any_switch_happened() == 1 ||*/ *no_tempering == 1 || record_change_state == 1))
{
record_change_state = 1;
check_if_tempering_happened = 0;
record_change_state = 0;
*no_tempering = 0;
}
else
{
#if 0
if (strcmp(viewChannelData[0].enable_ivs_and_ai, "Yes") == 0) {
if (strcmp(viewChannelData[0].enable_ivs_fix_mode, "Yes") == 0) {
for (int index_zone = 0; index_zone < viewChannelData[0].count_zone; index_zone++)
{
//if (strcmp(viewDetectionZone[0][index_zone].enable_ivs_zone, "Yes") == 0)
{
float min_x_points = (float)viewDetectionZone[0][index_zone].min_x_points * (float)ivs_width / (float)CANVAS_WIDTH;
float max_x_points = (float)viewDetectionZone[0][index_zone].max_x_points * (float)ivs_width / (float)CANVAS_WIDTH;
float min_y_points = (float)viewDetectionZone[0][index_zone].min_y_points * (float)ivs_height / (float)CANVAS_HEIGHT;
float max_y_points = (float)viewDetectionZone[0][index_zone].max_y_points * (float)ivs_height / (float)CANVAS_HEIGHT;
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = 0.8 * 100;
pNext->confidence2 = 0.8 * 100;
float temp_a_x = min_x_points;
float temp_a_y = min_y_points;
float temp_a_width = max_x_points - min_x_points;
float temp_a_height = max_y_points - min_y_points;
float thres_a_width = 8.0;
float thres_a_height = 6.0;
if (temp_a_x + temp_a_width < thres_a_width) {
temp_a_x = 0;
temp_a_width = thres_a_width;
}
else if (temp_a_x >= ivs_width - thres_a_width) {
temp_a_x = ivs_width - thres_a_width - 1;
temp_a_width = thres_a_width;
}
else {
if (temp_a_width < thres_a_width) {
temp_a_x -= (thres_a_width - temp_a_width) / 2.0;
temp_a_width = thres_a_width;
}
}
if (temp_a_y + temp_a_height < thres_a_height) {
temp_a_y = 0;
temp_a_height = thres_a_height;
}
else if (temp_a_y >= ivs_height - thres_a_height) {
temp_a_y = ivs_height - thres_a_height - 1;
temp_a_height = thres_a_height;
}
else {
if (temp_a_height < thres_a_height) {
temp_a_y -= (thres_a_height - temp_a_height) / 2.0;
temp_a_height = thres_a_height;
}
}
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = temp_a_x * ratio_width;
pNext->top_y = temp_a_y * ratio_height;
pNext->width = temp_a_width * ratio_width;
pNext->height = temp_a_height * ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 2;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
else {
for (int i = 0; i < (int)combine_rect_contours.size(); i++)
{
Rect bounding_for_a_object;
bounding_for_a_object = combine_rect_contours[i];
//current_store_object,不能放在last_store_object_size裡面
current_store_object_x[current_store_object_size] = bounding_for_a_object.x;
current_store_object_y[current_store_object_size] = bounding_for_a_object.y;
current_store_object_w[current_store_object_size] = bounding_for_a_object.width;
current_store_object_h[current_store_object_size] = bounding_for_a_object.height;
current_store_object_size++;
if (last_store_object_size >= 1) {
double intersect_ratio = 0.0;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
Rect bounding_for_b_object(last_store_object_x[index_last], last_store_object_y[index_last],
last_store_object_w[index_last], last_store_object_h[index_last]);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
if (bounding_for_intersection_object.area() >= 1)
{
double temp_intersect_ratio = (double)bounding_for_intersection_object.area() / (double)bounding_for_a_object.area();
if (temp_intersect_ratio > intersect_ratio) {
intersect_ratio = temp_intersect_ratio;
}
}
}
//Mat roi_a_object = masked_certain(bounding_for_a_object);
//double count_non_zero = ((double)countNonZero(roi_a_object)) / ((double)bounding_for_a_object.width*(double)bounding_for_a_object.height);
//roi_a_object.release();
//printf("\n---------count_non_zero:%lf\n", count_non_zero);
if (intersect_ratio >= (double)atoi(viewChannelData[0].confidence_unknown_object) / 100.0 /*&&
count_non_zero >= (double)atoi(viewChannelData[0].confidence2_unknown_object) / 100.0*/)
{
#if 0
printf("\n------------bounding_for_a_object.x:%d,bounding_for_a_object.y:%d\n", bounding_for_a_object.x, bounding_for_a_object.y);
#endif
if (PosInfo != NULL) {
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = intersect_ratio * 100;
pNext->confidence2 = 100;
float temp_a_x = (float)(bounding_for_a_object.x);
float temp_a_y = (float)(bounding_for_a_object.y);
float temp_a_width = (float)(bounding_for_a_object.width);
float temp_a_height = (float)(bounding_for_a_object.height);
float thres_a_width = 8.0;
float thres_a_height = 6.0;
if (temp_a_x + temp_a_width < thres_a_width) {
temp_a_x = 0;
temp_a_width = thres_a_width;
}
else if (temp_a_x >= ivs_width - thres_a_width) {
temp_a_x = ivs_width - thres_a_width - 1;
temp_a_width = thres_a_width;
}
else {
if (temp_a_width < thres_a_width) {
temp_a_x -= (thres_a_width - temp_a_width) / 2.0;
temp_a_width = thres_a_width;
}
}
if (temp_a_y + temp_a_height < thres_a_height) {
temp_a_y = 0;
temp_a_height = thres_a_height;
}
else if (temp_a_y >= ivs_height - thres_a_height) {
temp_a_y = ivs_height - thres_a_height - 1;
temp_a_height = thres_a_height;
}
else {
if (temp_a_height < thres_a_height) {
temp_a_y -= (thres_a_height - temp_a_height) / 2.0;
temp_a_height = thres_a_height;
}
}
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = temp_a_x * ratio_width;
pNext->top_y = temp_a_y * ratio_height;
pNext->width = temp_a_width * ratio_width;
pNext->height = temp_a_height * ratio_height;
pNext->center_x = pNext->left_x + pNext->width / 2;
pNext->center_y = pNext->top_y + pNext->height / 2;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 2;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
}
}
#endif
#if 1
for (int i = 0; i < (int)store_ivs_object.size() /*&& area_scale <= 0.45*/; i++) {
Rect bounding_for_a_object;
bounding_for_a_object = store_ivs_object[i];
if (//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
//(double)bounding_for_a_object.area() / ((double)ivs_width * (double)ivs_height) >= (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) > (double)atoi(viewChannelData[0].unknown_object_max_proportion) / 100.0 ||
(double)bounding_for_a_object.width / ((double)ivs_width) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
(double)bounding_for_a_object.height / ((double)ivs_height) <= (double)atoi(viewChannelData[0].unknown_object_min_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) > (double)atoi(viewChannelData[0].obj_max_proportion) / 100.0 ||
((double)bounding_for_a_object.width * (double)bounding_for_a_object.height) / (((double)ivs_width) * ((double)ivs_height)) < (double)atoi(viewChannelData[0].obj_min_proportion) / 100.0
//strcmp(viewChannelData[0].enable_show_unknown_object, "No") == 0
)
{
continue;
}
//current_store_object,不能放在last_store_object_size裡面
current_store_object_x[current_store_object_size] = bounding_for_a_object.x;
current_store_object_y[current_store_object_size] = bounding_for_a_object.y;
current_store_object_w[current_store_object_size] = bounding_for_a_object.width;
current_store_object_h[current_store_object_size] = bounding_for_a_object.height;
current_store_object_size++;
if (last_store_object_size >= 1) {
double intersect_ratio = 0.0;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
Rect bounding_for_b_object(last_store_object_x[index_last], last_store_object_y[index_last],
last_store_object_w[index_last], last_store_object_h[index_last]);
Rect bounding_for_intersection_object = bounding_for_a_object & bounding_for_b_object;
if (bounding_for_intersection_object.area() >= 1)
{
double temp_intersect_ratio = (double)bounding_for_intersection_object.area() / (double)bounding_for_a_object.area();
if (temp_intersect_ratio > intersect_ratio) {
intersect_ratio = temp_intersect_ratio;
}
}
}
//Mat roi_a_object = masked_certain(bounding_for_a_object);
//double count_non_zero = ((double)countNonZero(roi_a_object)) / ((double)bounding_for_a_object.width*(double)bounding_for_a_object.height);
//roi_a_object.release();
//printf("\n---------count_non_zero:%lf\n", count_non_zero);
if (intersect_ratio >= (double)atoi(viewChannelData[0].confidence_unknown_object) / 100.0 /*&&
count_non_zero >= (double)atoi(viewChannelData[0].confidence2_unknown_object) / 100.0*/) {
#if 0
printf("\n------------bounding_for_a_object.x:%d,bounding_for_a_object.y:%d\n", bounding_for_a_object.x, bounding_for_a_object.y);
#endif
float p_left_x = ((float)(bounding_for_a_object.x))*ratio_width;
float p_top_y = ((float)(bounding_for_a_object.y))*ratio_height;
float p_width = ((float)(bounding_for_a_object.width))*ratio_width;
float p_height = ((float)(bounding_for_a_object.height))*ratio_height;
float p_center_x = p_left_x + p_width / 2;
float p_center_y = p_top_y + p_height / 2;
if (valid_bbox_idx <= 25 && p_center_y < (float)i_InSourceOri_h * 2 / 3 && p_width / (float)i_InSourceOri_w <= 0.25) {
if (PosInfo != NULL) {
if (strcmp(heartbeatData.events_default_version, "4") == 0) {
if (p_width / (float)i_InSourceOri_w <= 0.25 && ((p_height * p_width) / ((float)i_InSourceOri_w * (float)i_InSourceOri_h)) >= 0.025)
{
int check_if_in_zone = 0;
for (int index_zone = 0; index_zone < viewChannelData[0].count_zone; index_zone++)
{
int temp_check_if_in_zone = check_if_object_in_zone_width_zone(p_center_x, p_center_y, p_width * 1.1, p_height * 1.1, (float)i_InSourceOri_w, (float)i_InSourceOri_h, 0, index_zone);
if (temp_check_if_in_zone == 1) {
check_if_in_zone = temp_check_if_in_zone;
break;
}
}
if (check_if_in_zone == 1) {
Mat a_object_hash_value = generateChecksumUsingHash(img_blur_hash, bounding_for_a_object);
if (!check_if_ivs_hash_has_been_recorded(a_object_hash_value))
{
push_back_to_record_hash(bounding_for_a_object, a_object_hash_value);
}
a_object_hash_value.release();
}
}
}
pNext = PosInfo + valid_bbox_idx;
memset(pNext->name, 0x00, sizeof(pNext->name));
strcpy(pNext->name, "object");
//pNext->confidence = (float)sqrt(intersect_ratio * (double)100)*10.0;
pNext->confidence = intersect_ratio * 100;
pNext->confidence2 = 100;
pNext->engine_type = FEATURE_TRAF_DET;//layerFeatureType[layer_idx];
pNext->engine_type2 = FEATURE_AIAREA;
pNext->left_x = p_left_x;
pNext->top_y = p_top_y;
pNext->width = p_width;
pNext->height = p_height;
pNext->center_x = p_center_x;
pNext->center_y = p_center_y;
pNext->parent_idx = -1;
pNext->car_logo_idx = -1;
pNext->number_row = 1;
pNext->class_id = 999;
pNext->box_x = pNext->left_x;
pNext->box_y = pNext->top_y;
pNext->box_w = pNext->width;
pNext->box_h = pNext->height;
pNext->obj_type = _PLATE;
valid_bbox_idx++;
}
}
}
}
}
#endif
last_store_object_size = current_store_object_size;
for (int index_last = 0; index_last < last_store_object_size; index_last++) {
last_store_object_x[index_last] = current_store_object_x[index_last];
last_store_object_y[index_last] = current_store_object_y[index_last];
last_store_object_w[index_last] = current_store_object_w[index_last];
last_store_object_h[index_last] = current_store_object_h[index_last];
}
}
}
else if (not_to_show_tempering == 0 && ((area_scale >= 0.95 && check_if_tempering_many_times <= 0) || tempering_ready == 1))
{
current_store_object_size = 0;
last_store_object_size = current_store_object_size;
//tempering_ready = 1;
check_if_tempering_happened = (temp_AI_fps - 1) * 2;
record_change_state = 0;
*no_tempering = 0;
tempering_ready = 0;
}
else if (not_to_show_tempering == 0 && (area_scale >= 0.95 && check_if_tempering_many_times >= 1))
{
current_store_object_size = 0;
last_store_object_size = current_store_object_size;
if (*no_tempering == 0 && record_change_state == 0) {
check_if_tempering_many_times--;
}
else if (*no_tempering == 1 || record_change_state == 1)
{
record_change_state = 1;
check_if_tempering_happened = 0;
record_change_state = 0;
*no_tempering = 0;
tempering_ready = 0;
}
}
dilate_img.release();
img_blur.release();
img_blur_hash.release();
for (int i = 0; i < (int)contours.size(); i++) {
contours[i].clear();
vector<Point>().swap(contours[i]);
}
contours.clear();
vector<vector<Point>>().swap(contours);
store_rect_contours.clear();
vector<Rect>().swap(store_rect_contours);
store_ivs_object.clear();
vector<Rect>().swap(store_ivs_object);
store_rect_contours_not_in_zone.clear();
vector<Rect>().swap(store_rect_contours_not_in_zone);
combine_rect_contours.clear();
vector<Rect>().swap(combine_rect_contours);
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
//masked_certain.release();
return (int)valid_bbox_idx;
}
}
}
}
int crop_image_ivs(char *output_image, int* image_size, char * snaphd_image_buffer, int snaphd_image_size, detection_pos* pNext, int i_InSourceOri_w, int i_InSourceOri_h) {
if (pNext == NULL)
return 0;
#ifdef GY_OS_AMBA
float ratio_width = (float)VIEW_WEB_WIDTH_HD / (float)i_InSourceOri_w;
float ratio_height = (float)VIEW_WEB_HEIGHT_HD / (float)i_InSourceOri_h;
#else
float ratio_width = (float)VIEW_WEB_WIDTH_SMALL / (float)i_InSourceOri_w;
float ratio_height = (float)VIEW_WEB_HEIGHT_SMALL / (float)i_InSourceOri_h;
#endif
int offset_x = (int)(pNext->left_x * ratio_width);
int offset_y = (int)(pNext->top_y * ratio_height);
int offset_w = (int)(pNext->width * ratio_width);
int offset_h = (int)(pNext->height * ratio_height);
if (offset_w == 0 || offset_h == 0) {
return 0;
}
#ifdef GY_OS_AMBA
if ((offset_x + offset_w) >= VIEW_WEB_WIDTH_HD) {
offset_w = VIEW_WEB_WIDTH_HD - offset_x;
}
if ((offset_y + offset_h) >= VIEW_WEB_HEIGHT_HD) {
offset_h = VIEW_WEB_HEIGHT_HD - offset_y;
}
#else
if ((offset_x + offset_w) >= VIEW_WEB_WIDTH_SMALL) {
offset_w = VIEW_WEB_WIDTH_SMALL - offset_x;
}
if ((offset_y + offset_h) >= VIEW_WEB_HEIGHT_SMALL) {
offset_h = VIEW_WEB_HEIGHT_SMALL - offset_y;
}
#endif
//printf("\n-------offset_x:%d,offset_y:%d,offset__w:%d,offset_h:%d\n", offset_x, offset_y, offset_w, offset_h);
int correct_color_index = 0;
int number_grid_width = 10;
int number_grid_height = 10;
double ratio_color_array[NUM_STRINGS_COLOR] = { 0 };
int sort_index_color[NUM_STRINGS_COLOR] = { 0 };
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_decode;
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
#ifdef GY_OS_AMBA
if (img_decode.size().width != VIEW_WEB_WIDTH_HD || img_decode.size().height != VIEW_WEB_HEIGHT_HD)
#else
if (img_decode.size().width != VIEW_WEB_WIDTH_SMALL || img_decode.size().height != VIEW_WEB_HEIGHT_SMALL)
#endif
{
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
return 0;
}
// Transform it into the C++ cv::Mat format
Mat image = img_decode.clone();
// Setup a rectangle to define your region of interest
Rect myROI(offset_x, offset_y, offset_w, offset_h);
// Crop the full image to that image contained by the rectangle myROI
// Note that this doesn't copy the data
Mat croppedImage = image(myROI);
Mat gray;
Mat hsv_image;
cvtColor(croppedImage, gray, COLOR_BGR2GRAY);
cvtColor(croppedImage, hsv_image, COLOR_BGR2HSV);
Mat blurred;
Mat hsv_blurred;
GaussianBlur(gray, blurred, Size(3, 3), 0);
GaussianBlur(hsv_image, hsv_blurred, Size(5, 5), 0);
Mat binaryIMG;
Canny(blurred, binaryIMG, 20, 160);
vector<vector<Point>> contours;
findContours(binaryIMG, contours, noArray(), RETR_LIST, CHAIN_APPROX_NONE);
vector<Point> store_all_points;
vector<Point> convexhull_points;
Point temp_point;
Point center_point;
for (int i = 0; i < (int)contours.size(); i++) {
for (int j = 0; j < (int)contours[i].size(); j++) {
if (contours[i][j].x >= (binaryIMG.cols / 20) && contours[i][j].x <= (binaryIMG.cols * 19 / 20) &&
contours[i][j].y >= (binaryIMG.rows*4 / 20) && contours[i][j].y <= (binaryIMG.rows * 18 / 20)) {
temp_point.x = contours[i][j].x;
temp_point.y = contours[i][j].y;
store_all_points.push_back(temp_point);
//circle(croppedImage, temp_point, 0, Scalar(0, 255, 0), -1, 8, 0);
}
}
}
if (store_all_points.size() >= 1) {
convexHull(store_all_points, convexhull_points);
if (convexhull_points.size() >= 1) {
Rect bounding_for_a_object;
bounding_for_a_object = boundingRect(convexhull_points);
if (bounding_for_a_object.width >= number_grid_width && bounding_for_a_object.height >= number_grid_height) {
for (int i = 0; i < number_grid_width; i++) {
for (int j = 0; j < number_grid_height; j++) {
//左上 右上 左下 右下 最上排 最下排 共32個扣掉
if (j == 0)
continue;
else if (j == 1 && (i <= 1 || i >= number_grid_width - 2))
continue;
else if (j == 2 && (i <= 0 || i >= number_grid_width - 1))
continue;
else if (j == number_grid_height - 3 && (i <= 0 || i >= number_grid_width - 1))
continue;
else if (j == number_grid_height - 2 && (i <= 1 || i >= number_grid_width - 2))
continue;
else if (j == number_grid_height - 1)
continue;
int x_grid = bounding_for_a_object.x + bounding_for_a_object.width*i / number_grid_width;
int y_grid = bounding_for_a_object.y + bounding_for_a_object.height*j / number_grid_height;
int width_grid = bounding_for_a_object.width / number_grid_width;
int height_grid = bounding_for_a_object.height / number_grid_height;
Rect a_grid(x_grid, y_grid, width_grid, height_grid);
Mat temp_hsv_blurred = hsv_blurred(a_grid);
Scalar scalar_hsv_value = mean(temp_hsv_blurred);
temp_hsv_blurred.release();
Scalar scalar_bgr_value;
double h_color = scalar_hsv_value[0] * 2.0;
double s_color = scalar_hsv_value[1] / 255.0;
double v_color = scalar_hsv_value[2] / 255.0;
//printf("\n------h_color:%lf\n", h_color);
//printf("\n------s_color:%lf\n", s_color);
//printf("\n------v_color:%lf\n", v_color);
if (h_color >= 15.0 && h_color < 30.0) {
if (v_color >= 0.12)
{
if (s_color <= 0.15) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 165, 255); //橘色
ratio_color_array[10]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color >= 30.0 && h_color <= 70.0) {
if (v_color >= 0.25)
{
if (s_color <= 0.20) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 255, 255); //黃色
ratio_color_array[5]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 70.0 && h_color <= 150.0) {
if (v_color >= 0.12)
{
if (s_color <= 0.07) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 255, 0); //綠色
ratio_color_array[6]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 150.0 && h_color <= 210.0) {
if (v_color >= 0.25)
{
if (s_color <= 0.25) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 255, 0); //青色
ratio_color_array[7]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 210.0 && h_color <= 270.0) {
if (v_color >= 0.25)
{
if (s_color <= 0.20) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 0, 0); //藍色
ratio_color_array[8]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 270.0 && h_color <= 330.0) {
if (v_color >= 0.25)
{
if (s_color <= 0.20) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 0, 255); //紫色
ratio_color_array[9]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else {
if (v_color >= 0.12)
{
if (s_color <= 0.07) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 255); //紅色
ratio_color_array[4]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
if (*image_size == 0) {
rectangle(croppedImage,
a_grid,
scalar_bgr_value,
1, 8, 0);
}
}
}
for (int i = 0; i < NUM_STRINGS_COLOR; i++) {
ratio_color_array[i] = ratio_color_array[i] / (double)(number_grid_width*number_grid_height - 32);
sort_index_color[i] = i;
}
for (int i = 0; i < NUM_STRINGS_COLOR - 1; i++) {
for (int j = i + 1; j < NUM_STRINGS_COLOR; j++) {
if (ratio_color_array[j] > ratio_color_array[i]) {
double temp_ratio = ratio_color_array[i];
double temp_index = sort_index_color[i];
ratio_color_array[i] = ratio_color_array[j];
sort_index_color[i] = sort_index_color[j];
ratio_color_array[j] = temp_ratio;
sort_index_color[j] = temp_index;
}
}
}
/*
for (int i = 0; i < NUM_STRINGS_COLOR; i++) {
printf("\ncolor index:%d,color name:%s,count ratio:%lf\n", sort_index_color[i], color_name[sort_index_color[i]], ratio_color_array[i]);
}*/
if (strcmp(color_name[sort_index_color[0]], "Blue") == 0) {
double sum_ratio_silver = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (strcmp(color_name[sort_index_color[i]], "Cyan") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
}
else if (strcmp(color_name[sort_index_color[i]], "Silver") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
}
}
if (sum_ratio_silver >= ratio_color_array[0]) {
correct_color_index = 1;
}
else if (ratio_color_array[0] >= 0.85) {
correct_color_index = 9;
}
else {
correct_color_index = sort_index_color[0];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Cyan") == 0) {
double sum_ratio_silver = 0;
double blue_ratio = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (strcmp(color_name[sort_index_color[i]], "Blue") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
blue_ratio = ratio_color_array[i];
}
else if (strcmp(color_name[sort_index_color[i]], "Silver") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
}
}
if (sum_ratio_silver >= ratio_color_array[0] && blue_ratio < 0.14) {
correct_color_index = 1;
}
else if (
ratio_color_array[0] >= 0.38 && ratio_color_array[0] < 0.68 &&
strcmp(color_name[sort_index_color[1]], "Darkgray") == 0 && ratio_color_array[1] >= 0.18 &&
(
(strcmp(color_name[sort_index_color[2]], "Blue") == 0 && ratio_color_array[2] >= 0.14 &&
strcmp(color_name[sort_index_color[3]], "Silver") == 0 && ratio_color_array[3] >= 0.1) ||
(strcmp(color_name[sort_index_color[2]], "Silver") == 0 && ratio_color_array[2] >= 0.14 &&
strcmp(color_name[sort_index_color[3]], "Blue") == 0 && ratio_color_array[3] >= 0.14)
)
)
{
correct_color_index = 1;
}
else if (ratio_color_array[0] >= 0.68)
{
correct_color_index = 8;
}
else {
correct_color_index = sort_index_color[0];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Red") == 0) {
int check_if_yellow = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (ratio_color_array[i] >= 0.12 && strcmp(color_name[sort_index_color[i]], "Yellow") == 0) {
check_if_yellow = 1;
}
}
if (check_if_yellow == 1) {
correct_color_index = 5;
}
else {
correct_color_index = sort_index_color[0];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Silver") == 0) {
if (ratio_color_array[0] >= 0.62) {
correct_color_index = 0;
}
else {
correct_color_index = sort_index_color[0];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Darkgray") == 0) {
if (ratio_color_array[0] >= 0.44) {
correct_color_index = sort_index_color[0];
}
else if (strcmp(color_name[sort_index_color[1]], "Red") == 0 && ratio_color_array[1] >= 0.12) {
correct_color_index = sort_index_color[1];
}
else if (strcmp(color_name[sort_index_color[1]], "Cyan") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = 1;
}
else if (strcmp(color_name[sort_index_color[1]], "Silver") == 0 && ratio_color_array[1] >= 0.13) {
correct_color_index = sort_index_color[1];
}
else if (strcmp(color_name[sort_index_color[1]], "Orange") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = sort_index_color[1];
}
else if (strcmp(color_name[sort_index_color[1]], "Green") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = sort_index_color[1];
}
else {
correct_color_index = sort_index_color[0];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Black") == 0) {
if (strcmp(color_name[sort_index_color[1]], "Darkgray") == 0 && ratio_color_array[1] <= 0.34) {
correct_color_index = sort_index_color[1];
}
else {
correct_color_index = sort_index_color[0];
}
}
else {
correct_color_index = sort_index_color[0];
}
if (correct_color_index == 2) {//convert Darkgray to Black
correct_color_index = 3;
}
else if (correct_color_index == 7) {//convert Cyan to Blue
correct_color_index = 8;
}
}
}
}
//printf("\n------------current_color:%s\n", color_name[correct_color_index]);
//polylines(croppedImage, convexhull_points,true, scalar_bgr_value,2,8,0);
//printf("\n----------size:%d\n", convexhull_points.size());
if (*image_size == 0) {
vector<uchar> data_encode;
imencode(".jpeg", croppedImage, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
for (int i = 0; i < (int)contours.size(); i++) {
contours[i].clear();
vector<Point>().swap(contours[i]);
}
contours.clear();
vector<vector<Point>>().swap(contours);
store_all_points.clear();
vector<Point>().swap(store_all_points);
convexhull_points.clear();
vector<Point>().swap(convexhull_points);
image.release();
croppedImage.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
gray.release();
hsv_blurred.release();
hsv_image.release();
blurred.release();
binaryIMG.release();
return color_id_array[correct_color_index];
}
#endif
int resize_image_ivs(char *output_image, int* image_size, char * snaphd_image_buffer, int snaphd_image_size, int snaphd_image_width, int snaphd_image_height,int resize_width,int resize_height) {
//int index_zone = 0;
int ret = 1;
/*
printf("\n------start:%d:%d\n", snaphd_image_width, snaphd_image_height);
for (int index_point = 0; index_point < 6; index_point++) {
printf("(%d)[x:%d,y:%d],",index_point, g_zone_polygon[index_zone][index_point].x * snaphd_image_width / CANVAS_WIDTH, g_zone_polygon[index_zone][index_point].y * snaphd_image_height / CANVAS_HEIGHT);
}
printf("\n------end:%d\n", snaphd_image_size);
*/
//printf("\n-------------crop zone image ivs-------2\n");
//printf("\n-------------crop zone image ivs-------3\n");
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_decode;
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\n-------------crop zone image ivs-------4\n");
if (img_decode.size().width != snaphd_image_width || img_decode.size().height != snaphd_image_height || resize_width <= 0 || resize_height <= 0) {
//printf("\n-------------crop zone image ivs-------5\n");
printf("\nimg decode size is error.\n");
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
ret = 0;
*image_size = 0;
}
else {
//printf("\n-------------crop zone image ivs-------6\n");
//printf("\n--------correct size\n");
Mat image = img_decode.clone();
Mat dstImage;
resize(image, dstImage, Size(resize_width, resize_height), 0, 0, INTER_CUBIC);
{
vector<uchar> data_encode;
vector<int> param = vector<int>(2);
param[0] = CV_IMWRITE_JPEG_QUALITY;
param[1] = 25; //default(95) 0-100
imencode(".jpeg", dstImage, data_encode, param);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
dstImage.release();
image.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
}
//printf("\n-------------crop zone image ivs-------7\n");
//printf("\n-------------crop zone image ivs-------8\n");
return ret;
}
int crop_zone_image_ivs(char *output_image, int* image_size, char * snaphd_image_buffer, int snaphd_image_size, int snaphd_image_width, int snaphd_image_height, int min_x_temp, int min_y_temp, int max_x_temp, int max_y_temp) {
//int index_zone = 0;
int ret = 1;
/*
printf("\n------start:%d:%d\n", snaphd_image_width, snaphd_image_height);
for (int index_point = 0; index_point < 6; index_point++) {
printf("(%d)[x:%d,y:%d],",index_point, g_zone_polygon[index_zone][index_point].x * snaphd_image_width / CANVAS_WIDTH, g_zone_polygon[index_zone][index_point].y * snaphd_image_height / CANVAS_HEIGHT);
}
printf("\n------end:%d\n", snaphd_image_size);
*/
//printf("\n-------------crop zone image ivs-------1\n");
int min_x = min_x_temp * snaphd_image_width / CANVAS_WIDTH;
int max_x = max_x_temp * snaphd_image_width / CANVAS_WIDTH;
int min_y = min_y_temp * snaphd_image_height / CANVAS_HEIGHT;
int max_y = max_y_temp * snaphd_image_height / CANVAS_HEIGHT;
//printf("\n-------------crop zone image ivs-------2\n");
if (max_x >= min_x + 1 && max_y >= min_y + 1 && min_x >= 1 && min_y >= 1 && max_x <= snaphd_image_width && max_y <= snaphd_image_height) {
//printf("\n-------------crop zone image ivs-------3\n");
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_decode;
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\n-------------crop zone image ivs-------4\n");
if (img_decode.size().width != snaphd_image_width || img_decode.size().height != snaphd_image_height) {
//printf("\n-------------crop zone image ivs-------5\n");
printf("\nimg decode size is error.\n");
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
ret = 0;
*image_size = 0;
}
else {
//printf("\n-------------crop zone image ivs-------6\n");
//printf("\n--------correct size\n");
Mat image = img_decode.clone();
Rect myROI(min_x, min_y, max_x - min_x, max_y - min_y);
Mat croppedImage = image(myROI);
{
vector<uchar> data_encode;
vector<int> param = vector<int>(2);
param[0] = CV_IMWRITE_JPEG_QUALITY;
param[1] = 25; //default(95) 0-100
imencode(".jpeg", croppedImage, data_encode, param);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
croppedImage.release();
image.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
}
//printf("\n-------------crop zone image ivs-------7\n");
}
else {
printf("\n[crop zone image ivs]zone x or y is error.\n");
ret = 0;
*image_size = 0;
}
//printf("\n-------------crop zone image ivs-------8\n");
return ret;
}
int find_zone_color(/*char *output_image, int* image_size,*/ char * snaphd_image_buffer, int snaphd_image_size, int snaphd_image_width, int snaphd_image_height, int min_x_temp, int min_y_temp, int max_x_temp, int max_y_temp) {
//int index_zone = 0;
int ret = 1;
/*
printf("\n------start:%d:%d\n", snaphd_image_width, snaphd_image_height);
for (int index_point = 0; index_point < 6; index_point++) {
printf("(%d)[x:%d,y:%d],",index_point, g_zone_polygon[index_zone][index_point].x * snaphd_image_width / CANVAS_WIDTH, g_zone_polygon[index_zone][index_point].y * snaphd_image_height / CANVAS_HEIGHT);
}
printf("\n------end:%d\n", snaphd_image_size);
*/
//printf("\n-------------crop zone image ivs-------1\n");
int min_x = min_x_temp * snaphd_image_width / CANVAS_WIDTH;
int max_x = max_x_temp * snaphd_image_width / CANVAS_WIDTH;
int min_y = min_y_temp * snaphd_image_height / CANVAS_HEIGHT;
int max_y = max_y_temp * snaphd_image_height / CANVAS_HEIGHT;
//printf("\n-------------crop zone image ivs-------2\n");
if (max_x >= min_x + 1 && max_y >= min_y + 1 && min_x >= 1 && min_y >= 1 && max_x <= snaphd_image_width && max_y <= snaphd_image_height) {
//printf("\n-------------crop zone image ivs-------3\n");
char img_buf_differ[MAX_IMG_SIZE] = { 0 };
Mat img_decode;
memcpy(img_buf_differ, snaphd_image_buffer, snaphd_image_size);
vector<uchar> vector_uchar(img_buf_differ, img_buf_differ + snaphd_image_size);
img_decode = imdecode(vector_uchar, CV_LOAD_IMAGE_COLOR);
//printf("\n-------------crop zone image ivs-------4\n");
if (img_decode.size().width != snaphd_image_width || img_decode.size().height != snaphd_image_height) {
//printf("\n-------------crop zone image ivs-------5\n");
printf("\nimg decode size is error.\n");
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
ret = 0;
//*image_size = 0;
}
else {
//printf("\n-------------crop zone image ivs-------6\n");
//printf("\n--------correct size\n");
Mat image = img_decode.clone();
Rect myROI(min_x, min_y, max_x - min_x, max_y - min_y);
Mat croppedImage = image(myROI);
Mat hsv_image, yuv_image, hsv_blurred, bgr_blurred, yuv_blurred;
cvtColor(croppedImage, hsv_image, COLOR_BGR2HSV);
cvtColor(croppedImage, yuv_image, COLOR_BGR2YUV);
GaussianBlur(hsv_image, hsv_blurred, Size(5, 5), 0);
GaussianBlur(croppedImage, bgr_blurred, Size(5, 5), 0);
GaussianBlur(yuv_image, yuv_blurred, Size(5, 5), 0);
vector<Mat> img_channels, bgr_channels, yuv_channels;
split(hsv_blurred, img_channels);
split(bgr_blurred, bgr_channels);
split(yuv_blurred, yuv_channels);
double h_color = single_channel_median(img_channels[0], 180) * 2.0;
double s_color = single_channel_median(img_channels[1], 256) / 255.0;
double v_color = single_channel_median(img_channels[2], 256) / 255.0;
double b_color = single_channel_median(bgr_channels[0], 256);
//double g_color = single_channel_median(bgr_channels[1], 256);
double r_color = single_channel_median(bgr_channels[2], 256);
double y_color = single_channel_median(yuv_channels[0], 256);
//double u_color = single_channel_median(yuv_channels[1], 256);
double vv_color = single_channel_median(yuv_channels[2], 256);
//printf("\n--------H:%f,S:%f,V:%f,B:%f,G:%f,R:%f,Y:%f,U:%f,VV:%f\n", h_color, s_color, v_color, b_color, g_color, r_color, y_color, u_color, vv_color);
if (h_color == 0.0 && s_color == 0.0) {//黑白模式
if (v_color >= 0.5 || r_color >= 128 || y_color >= 128) {
ret = 1;//紅燈
}
else {
ret = 0;//不是紅燈
}
}
else {//彩色模式
if ((v_color >= 0.5 || r_color >= 128 || vv_color >= 160) && r_color > b_color) {
ret = 1;//紅燈
}
else {
ret = 0;//不是紅燈
}
}
/*
{
vector<uchar> data_encode;
vector<int> param = vector<int>(2);
param[0] = CV_IMWRITE_JPEG_QUALITY;
param[1] = 25; //default(95) 0-100
imencode(".jpeg", croppedImage, data_encode, param);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}*/
bgr_channels[0].release();
bgr_channels[1].release();
bgr_channels[2].release();
bgr_channels.clear();
vector<Mat>().swap(bgr_channels);
yuv_channels[0].release();
yuv_channels[1].release();
yuv_channels[2].release();
yuv_channels.clear();
vector<Mat>().swap(yuv_channels);
bgr_blurred.release();
yuv_blurred.release();
yuv_image.release();
img_channels[0].release();
img_channels[1].release();
img_channels[2].release();
img_channels.clear();
vector<Mat>().swap(img_channels);
hsv_blurred.release();
hsv_image.release();
croppedImage.release();
image.release();
vector_uchar.clear();
vector<uchar>().swap(vector_uchar);
img_decode.release();
}
//printf("\n-------------crop zone image ivs-------7\n");
}
else {
printf("\n[find zone color]zone x or y is error.\n");
ret = 0;
//*image_size = 0;
}
//printf("\n-------------crop zone image ivs-------8\n");
return ret;
}
#if defined GY_OS_AMBA
int convert_to_general_image_for_lpr(char *output_image, int* image_size, char* __input_rgb_array__, int __width__, int __pitch__, int __height__, int __element_interleaved__, int *sec_color_id)
{
//pthread_mutex_lock(&mutex_color_detect);
//printf("\n------------------[Assign Object Color For Amba]----------------------start\n");
int i_object_width = __width__;
int i_object_pitch = __pitch__;
int i_object_height = __height__;
Mat tempImg;
//clock_t cputime0 = clock();
char* img_buf = new char[i_object_width * i_object_height * 3]; // RGB 3 channels
if (__element_interleaved__ == 0)
{
//tempImg = Mat(cvSize(i_object_width, i_object_height), CV_8UC3);
int i = 0, j = 0;
for (i = 0; i < i_object_height; i++)
{
for (j = 0; j < i_object_width; j++)
{
try
{
/*Vec3b& color = tempImg.at<Vec3b>(i, j); // Get the reference of the pixel
color[2] = __input_rgb_array__[i * i_object_pitch + j]; // Red
color[1] = __input_rgb_array__[i * i_object_pitch + j + i_object_pitch * i_object_height]; // Green
color[0] = __input_rgb_array__[i * i_object_pitch + j + i_object_pitch * i_object_height * 2]; // Blue*/
//tempImg.at<Vec3b>(j, i) = color; // Write back if not using the reference.
//printf("RGB(%d, %d)=(%d, %d, %d)\n", j, i, color[2], color[1], color[0]);
// Using the array transposition.
img_buf[i * i_object_width * 3 + j * 3] = __input_rgb_array__[i * i_object_pitch + j + i_object_pitch * i_object_height * 2]; // Blue
img_buf[i * i_object_width * 3 + j * 3 + 1] = __input_rgb_array__[i * i_object_pitch + j + i_object_pitch * i_object_height]; // Green
img_buf[i * i_object_width * 3 + j * 3 + 2] = __input_rgb_array__[i * i_object_pitch + j]; // Red
//printf("img_buf(%d, %d)=(%d, %d, %d)\n", i, j, img_buf[i * i_object_width * 3 + j * 3], img_buf[i * i_object_width * 3 + j * 3 + 1], img_buf[i * i_object_width * 3 + j * 3 + 2]);
}
catch (Exception& reason)
{
printf("Exception reason: %s\n", reason.what());
}
}
}
tempImg = Mat(i_object_height, i_object_width, CV_8UC3, img_buf); // Directly assign the array to the source of the Mat.
}
else
{
i_object_width = __width__;
i_object_pitch = __pitch__;
i_object_height = __height__;
tempImg = Mat(i_object_height, i_object_pitch, CV_8UC3, __input_rgb_array__);
}
int offset_w = (int)(tempImg.cols);
int offset_h = (int)(tempImg.rows);
if (offset_w == 0 || offset_h == 0) {
tempImg.release();
delete(img_buf);
return 0;
}
//printf("\n------offset__w:%d,offset_h:%d\n", offset_w, offset_h);
int correct_color_index = 0;
int correct_sec_color_index = -1;
int number_grid_width = 10;
int number_grid_height = 10;
double ratio_color_array[NUM_STRINGS_COLOR] = { 0 };
int sort_index_color[NUM_STRINGS_COLOR] = { 0 };
// Transform it into the C++ cv::Mat format
Mat image = tempImg.clone();
Mat gray;
Mat hsv_image;
cvtColor(image, gray, COLOR_BGR2GRAY);
cvtColor(image, hsv_image, COLOR_BGR2HSV);
Mat blurred;
Mat hsv_blurred;
GaussianBlur(gray, blurred, Size(3, 3), 0);
GaussianBlur(hsv_image, hsv_blurred, Size(5, 5), 0);
Mat binaryIMG;
Canny(blurred, binaryIMG, 20, 160);
vector<vector<Point>> contours;
findContours(binaryIMG, contours, noArray(), RETR_LIST, CHAIN_APPROX_NONE);
vector<Point> store_all_points;
vector<Point> convexhull_points;
Point temp_point;
Point center_point;
temp_point.x = offset_w * 2 / 10;
temp_point.y = offset_h * 2 / 10;
store_all_points.push_back(temp_point);
temp_point.x = offset_w * 8 / 10;
temp_point.y = offset_h * 2 / 10;
store_all_points.push_back(temp_point);
temp_point.x = offset_w * 8 / 10;
temp_point.y = offset_h * 8 / 10;
store_all_points.push_back(temp_point);
temp_point.x = offset_w * 2 / 10;
temp_point.y = offset_h * 8 / 10;
store_all_points.push_back(temp_point);
if (store_all_points.size() >= 1) {
convexHull(store_all_points, convexhull_points);
if (convexhull_points.size() >= 1) {
Rect bounding_for_a_object;
bounding_for_a_object = boundingRect(convexhull_points);
if (bounding_for_a_object.width >= number_grid_width && bounding_for_a_object.height >= number_grid_height) {
for (int i = 0 + 3; i < number_grid_width-3; i++) {
for (int j = 0 + 2; j < number_grid_height - 2; j++) {
//左上 右上 左下 右下 最上排 最下排 共32個扣掉
/*
if (j == 0)
continue;
else if (j == 1 && (i <= 1 || i >= number_grid_width - 2))
continue;
else if (j == 2 && (i <= 0 || i >= number_grid_width - 1))
continue;
else if (j == number_grid_height - 3 && (i <= 0 || i >= number_grid_width - 1))
continue;
else if (j == number_grid_height - 2 && (i <= 1 || i >= number_grid_width - 2))
continue;
else if (j == number_grid_height - 1)
continue;*/
int x_grid = bounding_for_a_object.x + bounding_for_a_object.width*i / number_grid_width;
int y_grid = bounding_for_a_object.y + bounding_for_a_object.height*j / number_grid_height;
int width_grid = bounding_for_a_object.width / number_grid_width;
int height_grid = bounding_for_a_object.height / number_grid_height;
Rect a_grid(x_grid, y_grid, width_grid, height_grid);
Mat temp_hsv_blurred = hsv_blurred(a_grid);
vector<Mat> img_channels;
split(temp_hsv_blurred, img_channels);
//Scalar scalar_hsv_value = mean(temp_hsv_blurred);
double h_color = single_channel_median(img_channels[0], 180) * 2.0;
double s_color = single_channel_median(img_channels[1], 256) / 255.0;
double v_color = single_channel_median(img_channels[2], 256) / 255.0;
temp_hsv_blurred.release();
img_channels[0].release();
img_channels[1].release();
img_channels[2].release();
img_channels.clear();
vector<Mat>().swap(img_channels);
Scalar scalar_bgr_value;
//double h_color = scalar_hsv_value[0] * 2.0;
//double s_color = scalar_hsv_value[1] / 255.0;
//double v_color = scalar_hsv_value[2] / 255.0;
//printf("\n------h_color:%lf\n", h_color);
//printf("\n------s_color:%lf\n", s_color);
//printf("\n------v_color:%lf\n", v_color);
/*
if (h_color >= 15.0 && h_color < 30.0) {
if (v_color >= 0.12)
{
if (s_color <= 0.15) {
if (v_color >= 0.75) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.75 && v_color >= 0.5) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 165, 255); //橘色
ratio_color_array[10]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}*/
if (h_color >= 22.0 && h_color <= 70.0) {//30
if (v_color >= 0.12)
{
if (s_color <= 0.07) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
if (v_color >= 0.85) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else {
scalar_bgr_value = Scalar(0, 255, 255); //黃色
ratio_color_array[5]++;
}
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 70.0 && h_color <= 190.0) {//150.0
if (v_color >= 0.12)
{
if (s_color <= 0.07) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
if (v_color >= 0.75 && h_color >= 150.0) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else {
scalar_bgr_value = Scalar(0, 255, 0); //綠色
ratio_color_array[6]++;
}
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 190.0 && h_color <= 210.0) {//150.0
if (v_color >= 0.25)
{
if (s_color <= 0.35) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 255, 0); //青色
ratio_color_array[7]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 210.0 && h_color <= 300.0) {//270
if (v_color >= 0.25)
{
if (s_color <= 0.25) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 0, 0); //藍色
ratio_color_array[8]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else if (h_color > 300.0 && h_color <= 330.0) {
if (v_color >= 0.25)
{
if (s_color <= 0.20) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(255, 0, 255); //紫色
ratio_color_array[9]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
else {
if (v_color >= 0.12)
{
if (s_color <= 0.07) {
if (v_color >= 0.65) {
scalar_bgr_value = Scalar(255, 255, 255);//白色
ratio_color_array[0]++;
}
else if (v_color < 0.65 && v_color >= 0.4) {
scalar_bgr_value = Scalar(170, 170, 170);//淺灰
ratio_color_array[1]++;
}
else {
scalar_bgr_value = Scalar(85, 85, 85);//深灰
ratio_color_array[2]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 255); //紅色
ratio_color_array[4]++;
}
}
else {
scalar_bgr_value = Scalar(0, 0, 0); //黑色
ratio_color_array[3]++;
}
}
}
}
for (int i = 0; i < NUM_STRINGS_COLOR; i++) {
ratio_color_array[i] = ratio_color_array[i] / (double)(number_grid_width*number_grid_height - 76);
sort_index_color[i] = i;
}
for (int i = 0; i < NUM_STRINGS_COLOR - 1; i++) {
for (int j = i + 1; j < NUM_STRINGS_COLOR; j++) {
if (ratio_color_array[j] > ratio_color_array[i]) {
double temp_ratio = ratio_color_array[i];
double temp_index = sort_index_color[i];
ratio_color_array[i] = ratio_color_array[j];
sort_index_color[i] = sort_index_color[j];
ratio_color_array[j] = temp_ratio;
sort_index_color[j] = temp_index;
}
}
}
/*
for (int i = 0; i < NUM_STRINGS_COLOR; i++) {
printf("\ncolor index:%d,color name:%s,count ratio:%lf\n", sort_index_color[i], color_name[sort_index_color[i]], ratio_color_array[i]);
}*/
if (strcmp(color_name[sort_index_color[0]], "Blue") == 0) {
double sum_ratio_silver = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (strcmp(color_name[sort_index_color[i]], "Cyan") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
}
else if (strcmp(color_name[sort_index_color[i]], "Silver") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
}
}
if (sum_ratio_silver >= ratio_color_array[0]) {
//correct_color_index = 1;
correct_color_index = sort_index_color[0];
if(ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (ratio_color_array[0] >= 0.85) {
//correct_color_index = 9;
correct_color_index = sort_index_color[0];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Cyan") == 0) {
double sum_ratio_silver = 0;
double blue_ratio = 0;
double sum_ratio_white = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (strcmp(color_name[sort_index_color[i]], "Blue") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
blue_ratio = ratio_color_array[i];
}
else if (strcmp(color_name[sort_index_color[i]], "Silver") == 0) {
sum_ratio_silver = sum_ratio_silver + ratio_color_array[i];
sum_ratio_white = sum_ratio_white + ratio_color_array[i];
}
else if (strcmp(color_name[sort_index_color[i]], "White") == 0) {
sum_ratio_white = sum_ratio_white + ratio_color_array[i];
}
}
if (sum_ratio_silver >= ratio_color_array[0] && blue_ratio < 0.14) {
correct_color_index = 1;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (
ratio_color_array[0] >= 0.38 && ratio_color_array[0] < 0.68 &&
strcmp(color_name[sort_index_color[1]], "Darkgray") == 0 && ratio_color_array[1] >= 0.18 &&
(
(strcmp(color_name[sort_index_color[2]], "Blue") == 0 && ratio_color_array[2] >= 0.14 &&
strcmp(color_name[sort_index_color[3]], "Silver") == 0 && ratio_color_array[3] >= 0.1) ||
(strcmp(color_name[sort_index_color[2]], "Silver") == 0 && ratio_color_array[2] >= 0.14 &&
strcmp(color_name[sort_index_color[3]], "Blue") == 0 && ratio_color_array[3] >= 0.14)
)
)
{
correct_color_index = 1;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (ratio_color_array[0] >= 0.68)
{
correct_color_index = 8;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (sum_ratio_white >= 0.30)
{
correct_color_index = 1;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Red") == 0) {
int check_if_yellow = 0;
for (int i = 1; i < NUM_STRINGS_COLOR; i++) {
if (ratio_color_array[i] >= 0.35 && strcmp(color_name[sort_index_color[i]], "Yellow") == 0) {
check_if_yellow = 1;
}
}
if (check_if_yellow == 1) {
correct_color_index = 5;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.21) {
correct_sec_color_index = sort_index_color[1];
//printf("\n----------red---%f\n", ratio_color_array[1]);
}
}
}
else if (strcmp(color_name[sort_index_color[0]], "Silver") == 0) {
if (ratio_color_array[0] >= 0.62) {
correct_color_index = 0;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Darkgray") == 0) {
if (ratio_color_array[0] >= 0.44) {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
else if (strcmp(color_name[sort_index_color[1]], "Red") == 0 && ratio_color_array[1] >= 0.12) {
correct_color_index = sort_index_color[1];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (strcmp(color_name[sort_index_color[1]], "Cyan") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = 1;
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (strcmp(color_name[sort_index_color[1]], "Silver") == 0 && ratio_color_array[1] >= 0.13) {
correct_color_index = sort_index_color[1];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (strcmp(color_name[sort_index_color[1]], "Orange") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = sort_index_color[1];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else if (strcmp(color_name[sort_index_color[1]], "Green") == 0 && ratio_color_array[1] >= 0.15) {
correct_color_index = sort_index_color[1];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
}
else if (strcmp(color_name[sort_index_color[0]], "Black") == 0) {
if (strcmp(color_name[sort_index_color[1]], "Darkgray") == 0 && ratio_color_array[1] <= 0.34) {
correct_color_index = sort_index_color[1];
if (ratio_color_array[0] > 0.1)
correct_sec_color_index = sort_index_color[0];
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
}
else {
correct_color_index = sort_index_color[0];
if (ratio_color_array[1] > 0.1)
correct_sec_color_index = sort_index_color[1];
}
if (correct_color_index == 2) {//convert Darkgray to Black
correct_color_index = 3;
}
else if (correct_color_index == 7) {//convert Cyan to Blue
correct_color_index = 8;
}
else if (correct_color_index == 1) {//convert Silver to White
correct_color_index = 0;
}
else if (correct_color_index == 9 || correct_color_index == 10) {//convert Orange and Purple to Red
correct_color_index = 4;
}
if (correct_sec_color_index == 2) {//convert Darkgray to Black
correct_sec_color_index = 3;
}
else if (correct_sec_color_index == 7) {//convert Cyan to Blue
correct_sec_color_index = 8;
}
else if (correct_sec_color_index == 1) {//convert Silver to White
correct_sec_color_index = 0;
}
else if (correct_sec_color_index == 9 || correct_sec_color_index == 10) {//convert Orange and Purple to Red
correct_sec_color_index = 4;
}
if (correct_color_index == correct_sec_color_index) {
for (int i = 0; i < NUM_STRINGS_COLOR; i++) {
if ((ratio_color_array[i] > 0.1 && sort_index_color[i] != correct_color_index && correct_color_index != 4 ) ||//not red
(ratio_color_array[i] > 0.21 && sort_index_color[i] != correct_color_index && correct_color_index == 4)) {//red
//printf("\n----------the same---%f\n", ratio_color_array[i]);
int temp_color_index = sort_index_color[i];
if (temp_color_index == 2) {//convert Darkgray to Black
temp_color_index = 3;
}
else if (temp_color_index == 7) {//convert Cyan to Blue
temp_color_index = 8;
}
else if (temp_color_index == 1) {//convert Silver to White
temp_color_index = 0;
}
else if (temp_color_index == 9 || temp_color_index == 10) {//convert Orange and Purple to Red
temp_color_index = 4;
}
if (temp_color_index != correct_color_index) {
correct_sec_color_index = temp_color_index;
break;
}
}
}
}
}
}
}
//printf("\n------------current_color:%s\n", color_name[correct_color_index]);
//printf("\n----------size:%d\n", convexhull_points.size());
if (*image_size == 0) {
vector<uchar> data_encode;
imencode(".jpeg", tempImg, data_encode);
string str_encode(data_encode.begin(), data_encode.end());
int length = (int)str_encode.length();
memcpy(output_image, str_encode.c_str(), length);
*image_size = length;
data_encode.clear();
vector<uchar>().swap(data_encode);
}
for (int i = 0; i < (int)contours.size(); i++) {
contours[i].clear();
vector<Point>().swap(contours[i]);
}
contours.clear();
vector<vector<Point>>().swap(contours);
store_all_points.clear();
vector<Point>().swap(store_all_points);
convexhull_points.clear();
vector<Point>().swap(convexhull_points);
image.release();
gray.release();
hsv_blurred.release();
hsv_image.release();
blurred.release();
binaryIMG.release();
tempImg.release();
delete(img_buf);
if (correct_sec_color_index >= 0) {
*sec_color_id = color_id_array[correct_sec_color_index];
}
else {
*sec_color_id = color_id_array[correct_color_index];
}
return color_id_array[correct_color_index];
}
#endif