Finding distance in a matrix in C - c

I have a matrix of numbers and want to find the distance of each item from its farthest non-zero neighbour (in four directions). I came up with this idea
#include <stdlib.h>
#include <stdio.h>
int min(int a, int b, int c, int d)
{
int e = a < b ? a : b;
int f = c < d ? c : d;
int r = e < f ? e : f;
return r;
}
int main()
{
int width = 50;
int height = 50;
int points[width][height];
int distances[width][height][5]; // 0 left 1 right 2 bottom 3 top 4 min
// adding some random values, zero and non-zero
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
points[x][y] = rand() % 100;
}
}
// scanning in four direction to check if the previous neighbour exists
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
}
for (int x = width - 1; x >= 0; x--)
{
if (points[x][y] > 0)
{
distances[x][y][1] = distances[x + 1][y][1] > 0 ? distances[x + 1][y][1] + 1 : 1;
}
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (points[x][y] > 0)
{
distances[x][y][2] = distances[x][y - 1][2] > 0 ? distances[x][y - 1][2] + 1 : 1;
}
}
for (int y = height - 1; y >= 0; y--)
{
if (points[x][y] > 0)
{
distances[x][y][3] = distances[x][y + 1][3] > 0 ? distances[x][y + 1][3] + 1 : 1;
}
}
}
// finding the minimum of four distances
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][4] = min(distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3]);
printf("%d %d %d %d %d %d %d \n", x, y, distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3], distances[x][y][4]);
}
}
}
return 0;
}
but it doesn't work as expected. Most likely, I have made a stupid mistake and have a blind eye for that to see.

At line 34:
if (points[x][y] > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
when x is zero, you are referencing up to 250 (50 * 5) words before the address of distances, which is an invalid thing to do.

Related

Calculating the distance of items from non-empty edges in a matrix

I have a matrix of 0 and 1
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 1 1 0 1 1 1 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1
0 0 1 1 1 1 1 0 0 0
0 0 0 0 1 1 0 1 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
I want to calculate the shortest distance of each item from the non-empty edges. You can assume it as pixels of black and white (or empty). We want to calculate the distance of each black pixel from the edge of the black body (through a straight line; horizontal, vertical or diagonal).
The distance is calculated geometrically: the distance of Ai,j and Ai+1,j+1 is sqrt(2).
With the following code in C, I started to calculate the distance of each item from its horizontal and vertical edges (in four directions). Now I want to consider diagonal distance too (at any angle, not just 45°).
The straightforward approach is to calculate the distance of each item from each edge. However, as the matrix gets larger, the loops become painfully slow.
Since we have the distance from horizontal and vertical edges for each item, I look for a hack to find the shortest distance to the edge by examining neighbour items in fewer checks.
#include <stdlib.h>
#include <stdio.h>
int min(int a, int b, int c, int d)
{
int e = a < b ? a : b;
int f = c < d ? c : d;
int r = e < f ? e : f;
return r;
}
int main()
{
int width = 50;
int height = 50;
int points[width][height];
int distances[width][height][5]; // 0 left 1 right 2 bottom 3 top 4 min
// some random data
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
points[x][y] = rand() % 2;
}
}
// scanning in four direction to check if the previous neighbour exists
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
if (x > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
else
{
distances[x][y][0] = 1;
}
}
}
for (int x = width - 1; x >= 0; x--)
{
if (points[x][y] > 0)
{
if (x < width - 1)
{
distances[x][y][1] = distances[x + 1][y][1] > 0 ? distances[x + 1][y][1] + 1 : 1;
}
else
{
distances[x][y][1] = 1;
}
}
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (points[x][y] > 0)
{
if (y > 0)
{
distances[x][y][2] = distances[x][y - 1][2] > 0 ? distances[x][y - 1][2] + 1 : 1;
}
else
{
distances[x][y][2] = 1;
}
}
}
for (int y = height - 1; y >= 0; y--)
{
if (points[x][y] > 0)
{
if (y < height - 1)
{
distances[x][y][3] = distances[x][y + 1][3] > 0 ? distances[x][y + 1][3] + 1 : 1;
}
else
{
distances[x][y][3] = 1;
}
}
}
}
// finding the minimum of four distances
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][4] = min(distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3]);
printf("%d %d %d %d %d %d %d \n", x, y, distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3], distances[x][y][4]);
}
}
}
return 0;
}
If I understood correctly, given an arbitrary body as the ameba-like shown below, you would like to find the shortest distance from its containing points (for instance, the black point in the figure below) to the edges of the black body. This is the distance shown in blue. And you would like to hopefully take advantage of the orthogonal distances already calculated (black straight lines in the figure) to find it quickly.
Since the shape is arbitrary and not many assumptions can be made about it, the only thing I could think of is to confine the search for the shortest distance to the bounding square shown below in green. The value of the green square side is two times the shortest orthogonal distance found in your algorithm (from the black point to the green point).
Another possible approach would be to get instead a 1/8, 1/4 or so of the size of this green square and if no edges are found, keep increasing it until you find one with a few edges. It is guaranteed that at least the last green square will have at least one edge point, which is the orthogonal distance itself.
Playing with some strategy to grow the green square, maybe you can get a satisfactory performance heuristically.
This solution is easier said than done when it comes to put it in code, but I'm not quite sure I got the problem correctly so I stopped here.
One issue I found is that the term "black body" is not well defined, and the matrix shown in the question does not have any sparse points so it's not random at all as the posted code generates. Does the black body allow holes in it? Even the word "edge" is confusing to me because my English is not very good and the term reminds me of the term used in graph theory which is actually a line segment.
I tried the code and its output seems correct and clear. Just noticed some rubbish is coming out from the not initialized distances variable. Easier to get this if you reduce the size of points array to 10x10 or so.
EDIT:
Here is a possible implementation of the first method. The function that calculates the shortest distance to the edge, taking into account a bounding square, is the get_min_dist_to_edge function. All edges are added to a list to reduce unnecessary checks. To get the first point of the list inside the bounding square, there is no way other than iterating the list from the beginning. In a use case with too many edges, this list can get too large. A hash table containing the elements of the list mapped to its y coordinate would allow to find the first element inside the square much faster, at the expense of some memory.
#include "ameba.h"
#include <sys/queue.h>
#include <search.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
struct point_entry_t {
int x;
int y;
LIST_ENTRY(point_entry_t) entries;
};
LIST_HEAD(slisthead, point_entry_t)
edges_list_head = LIST_HEAD_INITIALIZER(edges_list_head);
void add_point_to_edges_list(int x, int y)
{
static int list_initialized = 0;
if (list_initialized == 0) {
LIST_INIT(&edges_list_head);
list_initialized = 1;
}
struct point_entry_t *entry = malloc(sizeof(*entry));
if (entry) {
entry->x = x;
entry->y = y;
LIST_INSERT_HEAD(&edges_list_head, entry, entries);
}
}
void clear_list(void)
{
while (!LIST_EMPTY(&edges_list_head)) {
struct point_entry_t *n1 = LIST_FIRST(&edges_list_head);
LIST_REMOVE(n1, entries);
free(n1);
}
}
int min(int a, int b, int c, int d)
{
int e = a < b ? a : b;
int f = c < d ? c : d;
int r = e < f ? e : f;
return r;
}
int calc_distances(unsigned char points[80][80], int distances[80][80][5])
{
int width = 80;
int height = 80;
// scanning in four direction to check if the previous neighbour exists
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
if (x > 0)
{
distances[x][y][0] = distances[x - 1][y][0] > 0 ? distances[x - 1][y][0] + 1 : 1;
}
else
{
distances[x][y][0] = 1;
}
}
}
for (int x = width - 1; x >= 0; x--)
{
if (points[x][y] > 0)
{
if (x < width - 1)
{
distances[x][y][1] = distances[x + 1][y][1] > 0 ? distances[x + 1][y][1] + 1 : 1;
}
else
{
distances[x][y][1] = 1;
}
}
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (points[x][y] > 0)
{
if (y > 0)
{
distances[x][y][2] = distances[x][y - 1][2] > 0 ? distances[x][y - 1][2] + 1 : 1;
}
else
{
distances[x][y][2] = 1;
}
}
}
for (int y = height - 1; y >= 0; y--)
{
if (points[x][y] > 0)
{
if (y < height - 1)
{
distances[x][y][3] = distances[x][y + 1][3] > 0 ? distances[x][y + 1][3] + 1 : 1;
}
else
{
distances[x][y][3] = 1;
}
}
}
}
// finding the minimum of four distances
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (points[x][y] > 0)
{
distances[x][y][4] = min(distances[x][y][0], distances[x][y][1], distances[x][y][2], distances[x][y][3]);
if (distances[x][y][4] == 1)
add_point_to_edges_list(x, y);
}
}
}
}
void print_edges_and_points(int point_x, int point_y,
int min_dist_edge_x, int min_dist_edge_y,
int distances[80][80][5])
{
for (size_t y = 0; y < 80; y++) {
for (size_t x = 0; x < 80; x++) {
if ( x == min_dist_edge_x
&& y == min_dist_edge_y) {
printf("E");
} else if (distances[x][y][4] == 1) {
printf(".");
} else if ( x == point_x
&& y == point_y) {
printf("P");
} else {
printf(" ");
}
}
printf("\n");
}
}
static inline void get_boundaries(int x, int y, int distances[80][80][5],
int *boundary_start_x, int *boundary_finish_x,
int *boundary_start_y, int *boundary_finish_y)
{
*boundary_start_x = x - distances[x][y][4];
*boundary_start_y = y - distances[x][y][4];
*boundary_finish_x = x + distances[x][y][4];
*boundary_finish_y = y + distances[x][y][4];
if (*boundary_start_x < 0) *boundary_start_x = 0;
if (*boundary_start_y < 0) *boundary_start_y = 0;
if (*boundary_finish_x > 80) *boundary_finish_x = 80;
if (*boundary_finish_y > 80) *boundary_finish_y = 80;
}
float get_min_dist_to_edge(int x, int y, int distances[80][80][5],
int *edge_x, int *edge_y)
{
uint32_t min_sq_dist = INT_MAX;
int boundary_start_x; int boundary_finish_x;
int boundary_start_y; int boundary_finish_y;
get_boundaries(x, y, distances,
&boundary_start_x, &boundary_finish_x,
&boundary_start_y, &boundary_finish_y);
if (!LIST_EMPTY(&edges_list_head)) {
struct point_entry_t *entry = NULL;
LIST_FOREACH(entry, &edges_list_head, entries) {
if ( entry->y > boundary_finish_y
|| entry->x < boundary_start_x
|| entry->x > boundary_finish_x) {
continue;
} else if (entry->y < boundary_start_y) {
return sqrt(min_sq_dist);
}
int sq_dist = pow(abs(x - entry->x), 2) +
pow(abs(y - entry->y), 2);
if (sq_dist < min_sq_dist) {
*edge_x = entry->x;
*edge_y = entry->y;
min_sq_dist = sq_dist;
}
}
}
return -1;
}
int main(int nargs, char *argv[])
{
if (nargs != 3) {
printf("\tusage: %s <x> <y>\n", argv[0]);
return 0;
}
unsigned char (*points)[80] = (unsigned char (*)[80])ameba_bin;
int distances[80][80][5] = {0,}; // 0 left 1 right 2 bottom 3 top 4 min
int x = atoi(argv[1]);
int y = atoi(argv[2]);
int min_dist_edge_x = 0;
int min_dist_edge_y = 0;
calc_distances(points, distances);
float min_dist_edge = 0;
if ((min_dist_edge = get_min_dist_to_edge(x, y, distances, &min_dist_edge_x,
&min_dist_edge_y)) > 0) {
print_edges_and_points(x, y, min_dist_edge_x, min_dist_edge_y, distances);
printf("ortho distances for P (%d, %d): < %d, > %d, ^ %d, v %d\n", x, y,
distances[x][y][0], distances[x][y][1],
distances[x][y][2], distances[x][y][3]);
printf("min distance from P (%d, %d) to nearest edge point E (%d, %d) = %.02f\n", x, y,
min_dist_edge_x, min_dist_edge_y, min_dist_edge);
}
clear_list();
return 0;
}
Here is an output example:
$ gcc main.c -lm && ./a.out 35 40
.....
.... .....
.. ..
.. ..
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
E .
........ . .
. ... . .
.. ..... .
. .
. .
. .
. P .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.. .
. .
.. .
... .
... .
........... .
.... .
.. .
... .
... ..
.... ...
......
ortho distances for P (35, 40): < 31, > 37, ^ 28, v 24
min distance from P (35, 40) to nearest edge point E (27, 33) = 10.63
ameba.h was created using xxd -i over the output of a web-based tool that converts images to an ASCII table.
This problem is called "Euclidean Distance Transform". It can be solved exactly in O(NM) time. Here you can find a nice paper discussing the algorithm.
http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf
It works also for other norms like Manhattan or Chessboard distance.

To output a warning tone when detecting objects using darknet

I am working on a task to detect objects using darknet.
Regardless of the object names, if the threshold exceeds a certain level, I would like to have a warning sound output.
I don't know where to put the alarm output code.
The code below is the image.c currently in use.
#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.
}

I am trying to draw a circle with coordinate plane using loops in C programming but ıt does not give me the lower part of circle

As you see on the image there are no * in lower part of the circle. Why is that?
Equations in the loops: y = 10 - i , x = j-10 or k-10
Circle formula = r^2 = (x-a)^2 + (y-b)^2
int i, j, k;
for (i = 0; i < 21; i++) {
if (i == 10) {
for (j = 0; j < 21; j++) {
if (pow(r * r - (j -10 -a)*(j -10 -a), 0.5) + b == 0) {
printf("*");
}
else if (j == 10) {
printf("|");
}
else {
printf("-");
}
}
}
else {
for (k = 0; k < 21; k++) {
if (pow(r * r - (k -10 -a)*(k -10 -a), 0.5) + b == 10 - i) {
printf("*");
}
else if (k == 10) {
printf("|");
}
else {
printf(" ");
}
}
}
printf("\n");
}
enter image description here
You program should be more like this:
#include <stdio.h>
#include <math.h>
int main() {
int i, j, k;
int a = 3, b = 4, r = 5;
int x, y;
for (i = 0; i < 21; i++) {
y = -(i - 10);
if (y == 0) {
for (j = 0; j < 21; j++) {
x = j - 10;
if (r * r == pow(x - a, 2) + pow(y - b, 2)) {
printf("*");
}
else if (x == 0) {
printf("|");
}
else {
printf("-");
}
}
}
else {
for (k = 0; k < 21; k++) {
x = k - 10;
if (r * r == pow(x - a, 2) + pow(y - b, 2)) {
printf("*");
}
else if (x == 0) {
printf("|");
}
else {
printf(" ");
}
}
}
printf("\n");
}
}
When you match your equation, you should allow for (-3) ^ 2 is 9, while if you take the square root of 9, you could only match a 3, unless if you also check whether the "minus" of the square root is a 3, which is troublesome.
It might also be good that if you use x and y and do the calculations, and then at the last moment, map to the screen's method of displaying it, or a similar way, instead of using i and then -(i - 10) or 10 - i every where to mean y, so I added the x and y in your program. You might also comment that (a, b) is supposed to be the center of the circle.
There is also one point about, it seems the difference between y being 0 or not is that you print out the hyphen (for the x-axis), vs a space, so your program could be:
#include <stdio.h>
#include <math.h>
int main() {
int i, j;
int a = 3, b = 4, r = 5;
int x, y;
for (i = 0; i < 21; i++) {
y = -(i - 10);
for (j = 0; j < 21; j++) {
x = j - 10;
if (r * r == pow(x - a, 2) + pow(y - b, 2)) {
printf("*");
}
else if (x == 0) {
printf("|");
}
else {
printf(y == 0 ? "-" : " ");
}
}
printf("\n");
}
}
and in fact, you don't need i and j, but can directly iterate through x and y, as your way of displaying is only one character each time:
#include <stdio.h>
#include <math.h>
int main() {
int a = 3, b = 4, r = 5;
int x, y;
for (y = 10; y >= -10; y--) {
for (x = -10; x <= 10; x++) {
if (r * r == pow(x - a, 2) + pow(y - b, 2)) {
printf("*");
}
else if (x == 0) {
printf("|");
}
else {
printf(y == 0 ? "-" : " ");
}
}
printf("\n");
}
}

Expression Result Unused Greedy Algorithm

I have run this program and get the error expression result unused. I may be doing something simple wrong, but I have spent the day trying to figure it out to no avail. Any help you can provide is greatly appreciated.
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x - 25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10;
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5;
} y = y + 1;
if (x >= 1 && x < 5)
{ x - 1;
y= y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
if (x >= 25)
{
x - 25; // This accomplishes nothing
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10; // This accomplishes nothing
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5; // This accomplishes nothing
} y = y + 1;
if (x >= 1 && x < 5)
{
x - 1; // This accomplishes nothing
y= y + 1;
}
In each of those lines you're subtracting a number from x, but you're doing nothing with the result. If you're trying to update x with the result, you need to do just like you're doing with y, and put x = in front of the expression.
So if you want x to go down by 25, you should write:
x = x - 25;
Alternatively, you can write the shorthand:
x -= 25; // Note the equal sign
All the 4 statements x - 25, x- 10, x- 5, x - 1 will turn out to be useless unless you assign that value to x;
Because you are trying to subtract the value from x, but you are not assigning the new value to x.
Here is the solution of your problem:
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x = x - 25; //or x-=25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x = x - 10; //or x-=10;
y = y + 1;
}
if (x >= 5 && x < 10)
{
x = x - 5; //or x-=5;
y = y + 1;
}
if (x >= 1 && x < 5)
{
x = x - 1; //or x-=1; or x--; or --x; :)
y = y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
I would remain to be convinced about your loop structure. There's the division operator that can be used to good effect:
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
ncoins = amount / 25;
total += ncoins;
amount -= ncoins * 25;
assert(amount < 25);
ncoins = amount / 10;
total += ncoins;
amount -= ncoins * 10;
assert(amount < 10);
ncoins = amount / 5;
total += ncoins;
amount -= ncoins * 5;
assert(amount < 5);
total += amount;
That's written out longhand; you could devise a loop, too:
int values[] = { 25, 10, 5, 1 };
enum { N_VALUES = sizeof(values) / sizeof(values[0]) };
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
for (int i = 0; i < N_VALUES && amount > 0; i++)
{
ncoins = amount / values[i];
total += ncoins;
amount -= ncoins * values[i];
}
assert(amount == 0);

Bubble sort not working at all, if statement not executing

I'm working on a program which is going to be used to sort students test scores and eventually retrieve the mean, median, and the mode of the scores. For some strange reason my bubble sort is not working.. I'm unsure why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
int main (void)
{
char vStudents[N][15], trans = 'y', vTemp2;
int vScores[N], vTemp, x, i = 0, j=0, NewN;
printf("\t\tWhatsamatta U Scores System\n\n");
do
{
printf("Please Enter Students Name: ");
gets(vStudents[i]);
trans = 'N';
while (trans == 'N')
{
printf("Enter Students Score: ");
scanf("%d", &vScores[i]);
fflush(stdin);
if (vScores[i] >= 0 & vScores[i] <= 100)
trans = 'y';
else
printf("Score is invalid, please re-enter score.\n");
}
i++;
j++;
} while (j != N);
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
printf("%d %d %d\n\n", vScores[0], vScores[1], vScores[2]);
system("Pause");
return 0;
Any help would be useful, thanks in advance!
At least one error:
for(x = 0; x < vScores[N] - 1; x++)
{
if ((x < vScores[N] - 1) && (vScores[N] > vScores[N + 1]))
{
should be
for(x = 0; x <N - 1; x++)
{
if ((x < N - 1) && (vScores[N] > vScores[N + 1]))
{
//^^you should not compare index x with array elements
N is always 3. if we replace N in your code with 3, does it still make sense?
for(x = 0; x < vScores[3] - 1; x++)
{
if ((x < vScores[3] - 1) && (vScores[3] > vScores[3 + 1]))
{
vTemp = vScores[3];
vScores[3] = vScores[3 + 1];
vScores[3 + 1] = vTemp;
x = -1;
}
}
Ok, now that it is this:
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
Ask, when does i change?

Resources