How do I check if mutiple YOLO item overlap each other - c#

i need your help,and sorry about my poor English.
I using YOLOv4 to get detection object.
yolov4 can get object like cars, motorcycles, buses, etc.
and I want to using the result to check if car accident happen.
my perspective:
i think can check the all object in image
and try to detect whether two objects overlap.
And start to calculate the time at the same time.
If the two objects overlap for more than a period of time, it is judged as a car accident.
Describe the problem:
does anyone know how to check if the multiple Rectangle if overlap each other
i try to using that in C#
for (int i = 0; i < itemRectCar.Count - 1; i++)
{
if (itemRectCar[i].IntersectsWith(itemRectCar[i + 1]))
{
rectangle3 = Rectangle.Intersect(itemRectCar[i], itemRectCar[i + 1]);
itemRectCar[i].Intersect(itemRectCar[i + 1]);
if (!itemRectCar[i].IsEmpty)
{
graphics.DrawRectangle(penRed, rectangle3);
}
}
}
but this method only can work in a image can't be work in video
image
I need someone to inspire me.
thank you read my problem,hope you have a nice day

I think your issue is that you check car 1 vs car 2, car 2 vs car 3 etc. But what you don't do is to check car 1 vs car 5, or car 2 vs car 8
You basically want to check a collision of one car for all the other cars in the array, then you take the next car, and check for a collision with all other cars and so on.
To do that, you need a nested loop:
for (int i = 0; i < itemRectCar.Count; i++)
{
for (int j = 0; j < itemRectCar.Count; j++)
{
// A car shouldn't collect with itself, so skip this case
if (i == j)
continue;
if (itemRectCar[i].IntersectsWith(itemRectCar[j]))
{
rectangle3 = Rectangle.Intersect(itemRectCar[i], itemRectCar[j]);
itemRectCar[i].Intersect(itemRectCar[j]);
if (!itemRectCar[i].IsEmpty)
{
graphics.DrawRectangle(penRed, rectangle3);
}
}
}
}

Related

How can i fill a square with randomly sized squares and rectangles

So i need to know how i can go about filling an area with randomly sized rectangles and squares - like this for instance:
I already have a partially working demo however it has alot of instances in where it will not work and ontop of this it requires alot of manual checks which isn't the easiest thing to program nor is it efficient.
Ontop of the challenge at hand i'd like to also avoid using methods that require checking collision such as using an attached RigidBody2D or a Ray cast as i'm working with ui and would like to simply generate a table of locations and sizes for easier access (however if this is unavoidable i understand and please do still share your answer if this is the case)
I was hoping to simulate it in the sense of a table where you can merge cells together but i'm uncertain how this is achievable - if at all.
Thankyou in advance! :)
Edit:
In relation to UnholySheep's comment i found this. The Kd-Tree looks promising but (correct me if i'm wrong) i don't believe it can be immplemented in csharp without programming out of scope and i think it literally draws squares as opposed to implements gameobjects or Rect objects with a size and position.
Furthermore there's this thread but again it mentions using a Kd-Tree or methods which i want to avoid or as Brian said using a merge method which i don't think is achieavable in unity without programming an entire table module which is out of scope again. Additionally someone mentioned using a spiral which albeit is an interesting approach it wouldn't result in the randomness i want to achieve.
To clarify i am looking for a fairly simple algorithm - i don't believe a Kd-tree fits this but for anyone else this may be an option as there are unity modules for this.
Your question is a challange, plus writing code that perfectly produces the image takes a lot of time and patience. But here I wrote code that puts a field of all kinds of letters in a 2D array. As long as this array is empty it will allow itself to fill them with random rectangles.
public enum squareType { none, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, Y, W, X, Z }
public squareType[,] cases = new squareType[4,4];
public void Start()
{
var lengthX = cases.GetLength(0);
var lengthY = cases.GetLength(1);
var index = 0;
for (var i = 0; i < lengthX; i++)
{
for (var j = 0; j < lengthY; j++)
{
if (cases[i,j] != squareType.none) continue;
var randomX = Random.Range(i, Mathf.Min(i+3, lengthX));
var randomY = Random.Range(j, Mathf.Min(j+3, lengthY));
var color = (squareType) Enum.ToObject(typeof(squareType), ++index);
for (var x = i; x <= randomX; x++)
{
for (var y = j; y <= randomY; y++) cases[x, y] = color;
}
}
}
// Debug table
for (var i = 0; i < lengthX; i++)
{
var xField = "";
for (var j = 0; j < lengthY; j++) xField += " | " + cases[i, j];
Debug.Log(xField);
}
}
Example Result 4x4:
Example Result 6x6:

Dealing Cards game: x cards per y over z Amount of Players Algorithm in C#

I've been trying to come up with an algorithm which deals, as the title states,
X amount of Cards, per Y amount of Cards, over Z amount of Players of a normal (52 piece) Deck of Cards which is sorted or unsorted. I've been walking into a wall for the past few hours to come up with a working solution, while also Googling to find similar problems. Unfortunately without success, hence this question.
An example would be: dealing 2 Cards, per 1, over 2 Players would result in
Player 1 receiving 1 card
Player 2 receiving 1 card
Player 1 receiving 1 card
Player 2 receiving 1 card
Until now I have a solution with which I'm able to run my application, although the actual dealing algorithm isn't keeping the 'per' parameter into account. It will deal the right amount of cards to the Y amount of players, although each player will receive the total amount to be dealed in 1 go..
I was wondering if anyone here had to handle a similar problem in the past? Or could guide me into the right direction? :/
public List<Card>[] Deel(int per, int players, int cards)
{
_currentCard= 0;
List<Card>[] output = new List<Card>[players];
if (_cardsDistributed < _deck.Count)
{
for (int i = 0; i < players; i++)
{
List<Card> hand = new List<Card>();
for (int j = 0; j < cards; j++)
{
_currentCard= 0;
hand.Add(_deck[_currentCard]);
_deck.Remove(_deck[_currentCard]);
_cardsDistributed++;
}
output[i] = hand;
}
return output;
}
else
return null;
}
One way to think about this is to get a deck of cards and do it yourself, by hand, and write down the steps. For example, you have three players and you want to deal each player four cards, two at a time. So what do you do?
You take the deck in hand, hold it over the first player's pile, and deal two cards. The code for that is pretty simple:
player = 1
for i = 1 to 2
deal next card to player
Then you move to the second player's pile and deal two cards, and you do the same thing for the third player. So you need a loop to go through the players:
for player = 1 to 3
for i = 1 to 2
deal next card to player
At this point you've dealt two cards to each of the three players.
If you want to deal X cards Y at a time, and Y is smaller than X, then you need to go around to each player multiple times. How many? Well, how many times does Y go into X? The answer is X/Y.
If you were doing this by hand, you would start over at player 1, deal him two cards, move on to player 2, etc. Adding that in code is simple:
numRounds = 4/2
for round = 1 to numRounds
for player = 1 to 3
for card = 1 to 2
deal next card to player
Now, replace the constant values with X, Y, and Z, and try it with some other combination by following those exact steps. Deal six cards to each player, three at a time. Did it work? Try a few other combinations to verify that the steps you wrote down always work.
Once you've determined that the algorithm you've developed works, then writing the code to implement it on the computer is easy. There are, of course, some minor details like how to deal a card, but those are easy compared to figuring out the overall approach to the problem.
I was fortunate that I discovered this approach to problem solving early in my education. Casting an algorithmic problem into physical terms lets me build a model that I can play with, and write down the steps I took to solve the problem. After that, writing the program is a simple matter of duplicating those steps in code. It doesn't work for all problems, but it's very effective for a large number of different problems that you will encounter.
If I understood your question correctly you need something like this:
public List<Card>[] Deel(int per, int players, int cards)
{
List<Card>[] output = new List<Card>[players];
// init hand for each player
for (int i = 0; i < players; i++)
{
output[i] = new List<Card>();
}
// assume the number of cards is divided by 'per' without a remainder
// otherwise you need one more round to deal rest (cards % per) cards
int rounds = cards / per;
for (int round = 0; round < rounds; round++)
{
for (int i = 0; i < players; i++)
{
for (int j = 0; j < per; j++)
{
if (_deck.Count > 0)
{
output[i].Add(_deck[0]);
_deck.Remove(_deck[0]);
_cardsDistributed++;
}
else
{
// should throw an exception because the deck contains no more cards
// or maybe you need to check it before dealing
}
}
}
}
return output;
}

Can't figure out infinite loop

I have a list of potential sites to place landing pads in a 2d array. They're kept in 2 ints, one for row and one for column. I need to Randomly add a few landing sites from this list but for some reason it more often than not uses the same spots. I'd like to exclude these spots somehow so I used this loop but it locks up into an infinite loop for some reason and I just can't figure out why!
for(int j = 0; j < amountLandingPads; j++)
{
int r = Random.Range(0,potSitesC.Length-1);
while(roomType[potSitesR[r],potSitesC[r]] == (int)room.Landing)
{
r = Random.Range(0,potSitesC.Length-1);
}
roomType[potSitesR[r],potSitesC[r]] = (int)room.Landing;
//do more stuff
}
To me it looks like if the current site is already designated as a landing site, randomly choose another until you find a site that isn't a landing pad, what am I doing wrong?
potSites.Length is always gonna be 20+ and ammountLandingPads is always potsites.Length/4 and minimum 1.
roomtype is the type of room at that position (in a 2d int array)
It looks like you're using the same int r and also potSitesR.Length to decide both the row-coord and the column-coord of the landing site. This will end up always selecting positions from both potSitesR and potSitesC with the same indices, i.e. (potSitesR[1], potSitesC[1]), or (potSitesR[2], potSitesC[2]), and so on... and always within the potSitesR.Length range.
Try using a different value for both for more randomization. Here's example code:
for(int j = 0; j < amountLandingPads; j++)
{
//In the following statement
//Removed -1 because int version is exclusive of second parameter
//Changed it to potSitesR.Length (from potSitesC.Length)
int r = Random.Range(0, potSitesR.Length);
//second randomized number for column-randomization.
int c = Random.Range(0, potSitesC.Length);
while (roomType[potSitesR[r],potSitesC[c]] == (int)room.Landing) //using both randomized numbers
{
r = Random.Range(0, potSitesR.Length); // r from potSitesR.Length
c = Random.Range(0, potSitesC.Length); // c from potSitesC.Length
}
roomType[potSitesR[r], potSitesC[c]] = (int)room.Landing;
//do more stuff
}
I hope that helps!

Determine Item QtyStock after Order using C# and Excel

How can I cycle trough each order an check if I still have material to make that order?
For example in this image, I want to make an alert when there isn't enough material to produce the order.
I was thinking something like using a double for, but im having a really hard time getting the logic together.
If anyone can help me understand the logic in this problem I would appreciate it
On my Excel file I just used a simple formula (=F3-J3) and (=K3-J4) for the Metal Material.
I want to make an application witch reads the excel file using "Microsoft.Office.Interop.Excel" and "DataTable". I learned how to read the data and save it on the DataTable, just don't know how to cycle trough the rows and make the subtraction.
Thx.
I made a double for loop like I sugested, Im just wondering now if there is a way to optimize the code, or if there are any error, for now its seams to get the job done.
public void Method(){
for (int i = 1; i < dataGridView2.Rows.Count; i++)
{
string partnumber = dataGridView2.Rows[i - 1].Cells["PART NUMBER"].Value.ToString();
double onhand = double.Parse(dataGridView2.Rows[i - 1].Cells["TOTAL-ON-HAND"].Value.ToString());
for (int j = 1; j < dataGridView1.Rows.Count; j++)
{
string part = dataGridView1.Rows[j - 1].Cells["Part #"].Value.ToString();
double BL = double.Parse( dataGridView1.Rows[j - 1].Cells["BL"].Value.ToString());
if(partnumber == part)
{
if (onhand >= BL)
{
onhand = onhand - BL;
MessageBox.Show(partnumber.ToString() +": " + onhand.ToString());
}
else { break; }
}
}
}
Note: BL = Customer Order Qty

Modify items in List<T> fast

I tried to make this code perform faster using Parallel.ForEach and ConcurrentBag but it's still running way to long (esp. when having in mind that in my scenario i may also be 1.000.000++):
List<Point> points = new List<Point>();
for(int i = 0; i<100000;i++) {
Point point = new Point {X = i-50000, Y = i+50000, CanDelete = false};
points.Add(point);
}
foreach (Point point in points) {
foreach (Point innerPoint in points) {
if (innerPoint.CanDelete == false && (point.X - innerPoint.X) < 2) {
innerPoint.Y = point.Y;
point.CanDelete = true;
}
}
}
That code will perform WORSE in parallel, due to the data access patterns.
The best way to speed it up is to recognize that you don't need to consider all O(N^2) pairs of points, but only the ones having nearby X-coordinates.
First, sort the list by X-coordinate, O(N log N), then process forward and backward in the list from each point until you leave the neighborhood. You'll need to use indexing and not foreach.
If your sample data, the list is already sorted.
Since your distance test is symmetric, and removes matching points from consideration, you can skip looking at earlier points.
for (int j = 0; j < points.Length; ++j) {
int x1 = points[j].X;
//for (int k = j; k >= 0 && points[k].X > x1 - 2; --k ) { /* merge points */ }
for (int k = j + 1; k < points.Length && points[k].X < x1 + 2; ++k ) { /* merge points */ }
}
Not only is the complexity better, the cache behavior is far superior. And it can be split among multiple threads with far less cache contention.
Well, I don't know exactly what do you want, but let's try.
First, when creating the List, you might want to set it's desired initial size, since you know how many items it will hold. So it does not need to grow all the time.
List<Point> points = new List<Point>(100000);
Next, you could sort the list by the X property. So you would only compare each point with the points that are near it: when you find the first, forward or backward, that is too distant, you can stop comparing.

Categories

Resources