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
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 |