c - 使用暗网检测物体时输出警告音
问题描述
我正在执行一项使用暗网检测对象的任务。
无论对象名称如何,如果阈值超过一定水平,我希望有一个警告声音输出。
我不知道在哪里放置警报输出代码。
下面的代码是当前使用的 image.c。
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "image.h"
#include "utils.h"
#include "blas.h"
#include "dark_cuda.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <mmsystem.h>
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <math.h>
#pragma comment(lib, "winmm.lib")
#define SOUND_NAME "alarm2.wav"
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#endif
#ifndef STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#endif
extern int check_mistakes;
//int windows = 0;
float colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
float get_color(int c, int x, int max)
{
float ratio = ((float)x/max)*5;
int i = floor(ratio);
int j = ceil(ratio);
ratio -= i;
float r = (1-ratio) * colors[i][c] + ratio*colors[j][c];
//printf("%f\n", r);
return r;
}
static float get_pixel(image m, int x, int y, int c)
{
assert(x < m.w && y < m.h && c < m.c);
return m.data[c*m.h*m.w + y*m.w + x];
}
static float get_pixel_extend(image m, int x, int y, int c)
{
if (x < 0 || x >= m.w || y < 0 || y >= m.h) return 0;
/*
if(x < 0) x = 0;
if(x >= m.w) x = m.w-1;
if(y < 0) y = 0;
if(y >= m.h) y = m.h-1;
*/
if (c < 0 || c >= m.c) return 0;
return get_pixel(m, x, y, c);
}
static void set_pixel(image m, int x, int y, int c, float val)
{
if (x < 0 || y < 0 || c < 0 || x >= m.w || y >= m.h || c >= m.c) return;
assert(x < m.w && y < m.h && c < m.c);
m.data[c*m.h*m.w + y*m.w + x] = val;
}
static void add_pixel(image m, int x, int y, int c, float val)
{
assert(x < m.w && y < m.h && c < m.c);
m.data[c*m.h*m.w + y*m.w + x] += val;
}
void composite_image(image source, image dest, int dx, int dy)
{
int x,y,k;
for(k = 0; k < source.c; ++k){
for(y = 0; y < source.h; ++y){
for(x = 0; x < source.w; ++x){
float val = get_pixel(source, x, y, k);
float val2 = get_pixel_extend(dest, dx+x, dy+y, k);
set_pixel(dest, dx+x, dy+y, k, val * val2);
}
}
}
}
image border_image(image a, int border)
{
image b = make_image(a.w + 2*border, a.h + 2*border, a.c);
int x,y,k;
for(k = 0; k < b.c; ++k){
for(y = 0; y < b.h; ++y){
for(x = 0; x < b.w; ++x){
float val = get_pixel_extend(a, x - border, y - border, k);
if(x - border < 0 || x - border >= a.w || y - border < 0 || y - border >= a.h) val = 1;
set_pixel(b, x, y, k, val);
}
}
}
return b;
}
image tile_images(image a, image b, int dx)
{
if(a.w == 0) return copy_image(b);
image c = make_image(a.w + b.w + dx, (a.h > b.h) ? a.h : b.h, (a.c > b.c) ? a.c : b.c);
fill_cpu(c.w*c.h*c.c, 1, c.data, 1);
embed_image(a, c, 0, 0);
composite_image(b, c, a.w + dx, 0);
return c;
}
image get_label(image **characters, char *string, int size)
{
if(size > 7) size = 7;
image label = make_empty_image(0,0,0);
while(*string){
image l = characters[size][(int)*string];
image n = tile_images(label, l, -size - 1 + (size+1)/2);
free_image(label);
label = n;
++string;
}
image b = border_image(label, label.h*.25);
free_image(label);
return b;
}
image get_label_v3(image **characters, char *string, int size)
{
size = size / 10;
if (size > 7) size = 7;
image label = make_empty_image(0, 0, 0);
while (*string) {
image l = characters[size][(int)*string];
image n = tile_images(label, l, -size - 1 + (size + 1) / 2);
free_image(label);
label = n;
++string;
}
image b = border_image(label, label.h*.05);
free_image(label);
return b;
}
void draw_label(image a, int r, int c, image label, const float *rgb)
{
int w = label.w;
int h = label.h;
if (r - h >= 0) r = r - h;
int i, j, k;
for(j = 0; j < h && j + r < a.h; ++j){
for(i = 0; i < w && i + c < a.w; ++i){
for(k = 0; k < label.c; ++k){
float val = get_pixel(label, i, j, k);
set_pixel(a, i+c, j+r, k, rgb[k] * val);
}
}
}
}
void draw_weighted_label(image a, int r, int c, image label, const float *rgb, const float alpha)
{
int w = label.w;
int h = label.h;
if (r - h >= 0) r = r - h;
int i, j, k;
for (j = 0; j < h && j + r < a.h; ++j) {
for (i = 0; i < w && i + c < a.w; ++i) {
for (k = 0; k < label.c; ++k) {
float val1 = get_pixel(label, i, j, k);
float val2 = get_pixel(a, i + c, j + r, k);
float val_dst = val1 * rgb[k] * alpha + val2 * (1 - alpha);
set_pixel(a, i + c, j + r, k, val_dst);
}
}
}
}
void draw_box_bw(image a, int x1, int y1, int x2, int y2, float brightness)
{
//normalize_image(a);
int i;
if (x1 < 0) x1 = 0;
if (x1 >= a.w) x1 = a.w - 1;
if (x2 < 0) x2 = 0;
if (x2 >= a.w) x2 = a.w - 1;
if (y1 < 0) y1 = 0;
if (y1 >= a.h) y1 = a.h - 1;
if (y2 < 0) y2 = 0;
if (y2 >= a.h) y2 = a.h - 1;
for (i = x1; i <= x2; ++i) {
a.data[i + y1*a.w + 0 * a.w*a.h] = brightness;
a.data[i + y2*a.w + 0 * a.w*a.h] = brightness;
}
for (i = y1; i <= y2; ++i) {
a.data[x1 + i*a.w + 0 * a.w*a.h] = brightness;
a.data[x2 + i*a.w + 0 * a.w*a.h] = brightness;
}
}
void draw_box_width_bw(image a, int x1, int y1, int x2, int y2, int w, float brightness)
{
int i;
for (i = 0; i < w; ++i) {
float alternate_color = (w % 2) ? (brightness) : (1.0 - brightness);
draw_box_bw(a, x1 + i, y1 + i, x2 - i, y2 - i, alternate_color);
}
}
void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b)
{
//normalize_image(a);
int i;
if(x1 < 0) x1 = 0;
if(x1 >= a.w) x1 = a.w-1;
if(x2 < 0) x2 = 0;
if(x2 >= a.w) x2 = a.w-1;
if(y1 < 0) y1 = 0;
if(y1 >= a.h) y1 = a.h-1;
if(y2 < 0) y2 = 0;
if(y2 >= a.h) y2 = a.h-1;
for(i = x1; i <= x2; ++i){
a.data[i + y1*a.w + 0*a.w*a.h] = r;
a.data[i + y2*a.w + 0*a.w*a.h] = r;
a.data[i + y1*a.w + 1*a.w*a.h] = g;
a.data[i + y2*a.w + 1*a.w*a.h] = g;
a.data[i + y1*a.w + 2*a.w*a.h] = b;
a.data[i + y2*a.w + 2*a.w*a.h] = b;
}
for(i = y1; i <= y2; ++i){
a.data[x1 + i*a.w + 0*a.w*a.h] = r;
a.data[x2 + i*a.w + 0*a.w*a.h] = r;
a.data[x1 + i*a.w + 1*a.w*a.h] = g;
a.data[x2 + i*a.w + 1*a.w*a.h] = g;
a.data[x1 + i*a.w + 2*a.w*a.h] = b;
a.data[x2 + i*a.w + 2*a.w*a.h] = b;
}
}
void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b)
{
int i;
for(i = 0; i < w; ++i){
draw_box(a, x1+i, y1+i, x2-i, y2-i, r, g, b);
}
}
void draw_bbox(image a, box bbox, int w, float r, float g, float b)
{
int left = (bbox.x-bbox.w/2)*a.w;
int right = (bbox.x+bbox.w/2)*a.w;
int top = (bbox.y-bbox.h/2)*a.h;
int bot = (bbox.y+bbox.h/2)*a.h;
int i;
for(i = 0; i < w; ++i){
draw_box(a, left+i, top+i, right-i, bot-i, r, g, b);
}
}
image **load_alphabet()
{
int i, j;
const int nsize = 8;
image** alphabets = (image**)xcalloc(nsize, sizeof(image*));
for(j = 0; j < nsize; ++j){
alphabets[j] = (image*)xcalloc(128, sizeof(image));
for(i = 32; i < 127; ++i){
char buff[256];
sprintf(buff, "data/labels/%d_%d.png", i, j);
alphabets[j][i] = load_image_color(buff, 0, 0);
}
}
return alphabets;
}
// Creates array of detections with prob > thresh and fills best_class for them
detection_with_class* get_actual_detections(detection *dets, int dets_num, float thresh, int* selected_detections_num, char **names)
{
int selected_num = 0;
detection_with_class* result_arr = (detection_with_class*)xcalloc(dets_num, sizeof(detection_with_class));
int i;
for (i = 0; i < dets_num; ++i) {
int best_class = -1;
float best_class_prob = thresh;
int j;
for (j = 0; j < dets[i].classes; ++j) {
int show = strncmp(names[j], "dont_show", 9);
if (dets[i].prob[j] > best_class_prob && show) {
best_class = j;
best_class_prob = dets[i].prob[j];
}
}
if (best_class >= 0) {
result_arr[selected_num].det = dets[i];
result_arr[selected_num].best_class = best_class;
++selected_num;
}
}
if (selected_detections_num)
*selected_detections_num = selected_num;
return result_arr;
}
// compare to sort detection** by bbox.x
int compare_by_lefts(const void *a_ptr, const void *b_ptr) {
const detection_with_class* a = (detection_with_class*)a_ptr;
const detection_with_class* b = (detection_with_class*)b_ptr;
const float delta = (a->det.bbox.x - a->det.bbox.w/2) - (b->det.bbox.x - b->det.bbox.w/2);
return delta < 0 ? -1 : delta > 0 ? 1 : 0;
}
// compare to sort detection** by best_class probability
int compare_by_probs(const void *a_ptr, const void *b_ptr) {
const detection_with_class* a = (detection_with_class*)a_ptr;
const detection_with_class* b = (detection_with_class*)b_ptr;
float delta = a->det.prob[a->best_class] - b->det.prob[b->best_class];
return delta < 0 ? -1 : delta > 0 ? 1 : 0;
}
void draw_detections_v3(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes, int ext_output)
{
static int frame_id = 0;
frame_id++;
int selected_detections_num;
detection_with_class* selected_detections = get_actual_detections(dets, num, thresh, &selected_detections_num, names);
// text output
qsort(selected_detections, selected_detections_num, sizeof(*selected_detections), compare_by_lefts);
int i;
for (i = 0; i < selected_detections_num; ++i) {
const int best_class = selected_detections[i].best_class;
printf("%s: %.0f%%", names[best_class], selected_detections[i].det.prob[best_class] * 100);
if (ext_output)
printf("\t(left_x: %4.0f top_y: %4.0f width: %4.0f height: %4.0f)\n",
round((selected_detections[i].det.bbox.x - selected_detections[i].det.bbox.w / 2)*im.w),
round((selected_detections[i].det.bbox.y - selected_detections[i].det.bbox.h / 2)*im.h),
round(selected_detections[i].det.bbox.w*im.w), round(selected_detections[i].det.bbox.h*im.h));
else
printf("\n");
int j;
for (j = 0; j < classes; ++j) {
if (selected_detections[i].det.prob[j] > thresh && j != best_class) {
printf("%s: %.0f%%", names[j], selected_detections[i].det.prob[j] * 100);
if (ext_output)
printf("\t(left_x: %4.0f top_y: %4.0f width: %4.0f height: %4.0f)\n",
round((selected_detections[i].det.bbox.x - selected_detections[i].det.bbox.w / 2)*im.w),
round((selected_detections[i].det.bbox.y - selected_detections[i].det.bbox.h / 2)*im.h),
round(selected_detections[i].det.bbox.w*im.w), round(selected_detections[i].det.bbox.h*im.h));
else
printf("\n");
}
}
}
// image output
qsort(selected_detections, selected_detections_num, sizeof(*selected_detections), compare_by_probs);
for (i = 0; i < selected_detections_num; ++i) {
int width = im.h * .002;
if (width < 1)
width = 1;
/*
if(0){
width = pow(prob, 1./2.)*10+1;
alphabet = 0;
}
*/
//printf("%d %s: %.0f%%\n", i, names[selected_detections[i].best_class], prob*100);
int offset = selected_detections[i].best_class * 123457 % classes;
float red = get_color(2, offset, classes);
float green = get_color(1, offset, classes);
float blue = get_color(0, offset, classes);
float rgb[3];
//width = prob*20+2;
rgb[0] = red;
rgb[1] = green;
rgb[2] = blue;
box b = selected_detections[i].det.bbox;
//printf("%f %f %f %f\n", b.x, b.y, b.w, b.h);
int left = (b.x - b.w / 2.)*im.w;
int right = (b.x + b.w / 2.)*im.w;
int top = (b.y - b.h / 2.)*im.h;
int bot = (b.y + b.h / 2.)*im.h;
if (left < 0) left = 0;
if (right > im.w - 1) right = im.w - 1;
if (top < 0) top = 0;
if (bot > im.h - 1) bot = im.h - 1;
//int b_x_center = (left + right) / 2;
//int b_y_center = (top + bot) / 2;
//int b_width = right - left;
//int b_height = bot - top;
//sprintf(labelstr, "%d x %d - w: %d, h: %d", b_x_center, b_y_center, b_width, b_height);
// you should create directory: result_img
//static int copied_frame_id = -1;
//static image copy_img;
//if (copied_frame_id != frame_id) {
// copied_frame_id = frame_id;
// if (copy_img.data) free_image(copy_img);
// copy_img = copy_image(im);
//}
//image cropped_im = crop_image(copy_img, left, top, right - left, bot - top);
//static int img_id = 0;
//img_id++;
//char image_name[1024];
//int best_class_id = selected_detections[i].best_class;
//sprintf(image_name, "result_img/img_%d_%d_%d_%s.jpg", frame_id, img_id, best_class_id, names[best_class_id]);
//save_image(cropped_im, image_name);
//free_image(cropped_im);
if (im.c == 1) {
draw_box_width_bw(im, left, top, right, bot, width, 0.8); // 1 channel Black-White
}
else {
draw_box_width(im, left, top, right, bot, width, red, green, blue); // 3 channels RGB
}
if (alphabet) {
char labelstr[4096] = { 0 };
strcat(labelstr, names[selected_detections[i].best_class]);
char prob_str[10];
sprintf(prob_str, ": %.2f", selected_detections[i].det.prob[selected_detections[i].best_class]);
strcat(labelstr, prob_str);
int j;
for (j = 0; j < classes; ++j) {
if (selected_detections[i].det.prob[j] > thresh && j != selected_detections[i].best_class) {
strcat(labelstr, ", ");
strcat(labelstr, names[j]);
}
}
image label = get_label_v3(alphabet, labelstr, (im.h*.02));
//draw_label(im, top + width, left, label, rgb);
draw_weighted_label(im, top + width, left, label, rgb, 0.7);
free_image(label);
}
if (selected_detections[i].det.mask) {
image mask = float_to_image(14, 14, 1, selected_detections[i].det.mask);
image resized_mask = resize_image(mask, b.w*im.w, b.h*im.h);
image tmask = threshold_image(resized_mask, .5);
embed_image(tmask, im, left, top);
free_image(mask);
free_image(resized_mask);
free_image(tmask);
}
}
free(selected_detections);
}
void draw_detections(image im, int num, float thresh, box *boxes, float **probs, char **names, image **alphabet, int classes)
{
int i;
for(i = 0; i < num; ++i){
int class_id = max_index(probs[i], classes);
float prob = probs[i][class_id];
if(prob > thresh){
//// for comparison with OpenCV version of DNN Darknet Yolo v2
//printf("\n %f, %f, %f, %f, ", boxes[i].x, boxes[i].y, boxes[i].w, boxes[i].h);
// int k;
//for (k = 0; k < classes; ++k) {
// printf("%f, ", probs[i][k]);
//}
//printf("\n");
int width = im.h * .012;
if(0){
width = pow(prob, 1./2.)*10+1;
alphabet = 0;
}
int offset = class_id*123457 % classes;
float red = get_color(2,offset,classes);
float green = get_color(1,offset,classes);
float blue = get_color(0,offset,classes);
float rgb[3];
//width = prob*20+2;
rgb[0] = red;
rgb[1] = green;
rgb[2] = blue;
box b = boxes[i];
int left = (b.x-b.w/2.)*im.w;
int right = (b.x+b.w/2.)*im.w;
int top = (b.y-b.h/2.)*im.h;
int bot = (b.y+b.h/2.)*im.h;
if(left < 0) left = 0;
if(right > im.w-1) right = im.w-1;
if(top < 0) top = 0;
if(bot > im.h-1) bot = im.h-1;
printf("%s: %f%%", names[class_id], prob * 100);
//printf(" - id: %d, x_center: %d, y_center: %d, width: %d, height: %d",
// class_id, (right + left) / 2, (bot - top) / 2, right - left, bot - top);
printf("\n");
draw_box_width(im, left, top, right, bot, width, red, green, blue);
if (alphabet) {
image label = get_label(alphabet, names[class_id], (im.h*.03)/10);
draw_label(im, top + width, left, label, rgb);
}
}
}
}
解决方案
It is a design issue, rather then a right/wrong answer. I would suggest when in
draw_detections_v3()
when selected_detections_num > 0
:
int selected_detections_num = 0 ;
detection_with_class* selected_detections = get_actual_detections(dets, num, thresh, &selected_detections_num, names);
// Your alarm code here (example)
if( selected_detections_num )
{
putchar( `\a` ) ; // Audible alert to console - replace with
// suitable audible alert if you need.
}
推荐阅读
- c++ - 无法理解比较器的下限功能
- forms - Symfony 表单一次编辑多个对象
- algorithm - 查找用于生成序列中下一个数字的算法
- python - AttributeError:“ElementTree”对象在尝试导入 excel 文件时没有属性“getiterator”
- rust - 特质有时可以移动
- reactjs - 我可以在电子邮件模板中使用 Material-UI 吗?
- docker - Oracle 测试容器抛出“IO 错误:从读取调用中得到减一”
- python - 如何使其成为单线?将列表转换为一堆参数
- python - Python:BeautifulSoup - 从 location.href= 中提取值
- tensorflow - 自定义 Keras Metrics Class -> Metric 在某个召回值