Transformer une base ligne en matrice
Bonjour
Je teste un nouveau logiciel en ligne dans le cadre de mon travail qui me permet de compter à partir d'une vidéo tous les objets en mouvements.
Dans le test que je suis en train de faire, c'est une vidéo d'un carrefour où on me compte les voitures, les poids lourds, les piétons..
J'ai reçu le fichier joint
Je cherche à obtenir une matrice origine-destination par catégorie d'usagers et par un laps de temps défini (le quart d'heure pour cet exemple)
J'ai besoin d'obtenir une matrice comme illustré dans l'onglet rendu.
Pour ça, les colonnes L, Q, V, AA indiquent la direction (nord, sud, est et ouest), la colonne 1/4H le quart d'heure concerné, la colonne H la catégorie d'usagers.
Pour savoir quelle direction emprunte une voiture par exemple, si je le fait à la main, en prenant la ligne 6 du tableau
J'ai une voiture qui est passé de la branche Sud vers la branche Ouest car sur la vidéo, on l'a détecté sur la frame 1576 puis sur la 1652, j'ai donc le 1/4H concerné, la catégorie et le mouvement..
J'espère avoir été clair, je ne suis pas très futé sur Excel. Je ne connais que les fonctions de bases.
Je ne sais pas comment attaquer le problème
Merci de votre aide
Bonjour,
pas trop le temps pour l'instant mais ça pourra servir à d'autres :
les x ligne 26 c'est un résidu de test ou ton tableau peut réellement avoir autre chose que des numériques en L, Q, V AA ?
Et pour le rendu tu ne dis pas si le 1/4h suivant est en-dessous ou à droite.
Personnellement j'aurais plutôt vu le 1/4h répété sur chaque ligne en colonne A, ce qui te fera une base de données exploitable avec les TCD
eric
Bonjour Eric
Merci pour ton retour
Les x sont des résidus de mon test..
L'autre 1/4H est en dessous
Après je ne vois pas trop comment faire avec les TCD, j'ai pourtant essayé mais j'imagine qu'il doit y avoir un traitement intermédiaire à faire.
Je disais avoir la possibilité de créer des TCD à partir des données mises en forme dans ton rendu.
Pour ça il faut il faut respecter certaines règles dont celle-ci.
eriiic a écrit :Je disais avoir la possibilité de créer des TCD à partir des données mises en forme dans ton rendu.
Pour ça il faut il faut respecter certaines règles dont celle-ci.
ok, j'attends de voir pour comprendre.
Merci
comme ça :
D'ailleurs ne faudrait-il pas ajouter la date si demain tu as plusieurs jours dans l'extraction ?
1 seule frame je suppose qu'on élimine mais que faire des 3 ou 4 frames ?
Elimination directe ou comptage de 2 ou 3 passages pour la ligne ?
Ou bien on peut aussi ajouter 3 champs pour les comptabiliser : 1 frame, 3 frames et 4 frames
Oui c'est très bien comme ça
si effectivement la date est importante
1 seule trame, on élimine. Peux on savoir cela représente combien de frame par direction ? d'un autre côté avec des filtres simples on peux le savoir donc ce n'est pas forcément important
La dernière solution parait bonne pour en connaître le nombre de frames "déchets" et répond à ma question ci-dessus..
merci
Donc 3 et 4 frames on compte dans un coin comme pour 1 frame ?
Pour 3 je comprend mais pour 4... Le gars qui va chercher son pain et revient par le même chemin en moins d'1/4h n'est pas un cas indécidable, pour moi c'est 2 passages. Non ? Enfin c'est toi qui vois
oui stp
Normalement 1 ligne = 1 trajet donc s'il passe par les 4 frames sur la même ligne c'est qu'il est passé par les 4 branches sans jamais quitter la zone filmé sinon une autre ligne aurait été créée
merci
Bonjour,
un peu plus compliqué que ce que je pensais.
Voilà le début que tu commences les contrôles (une horreur
Je n'ai contrôlé que Est vers Ouest et Ouest vers Est du 1er 1/4h.
Si tu pouvais en contrôler un plus pour valider, en priorité celui qui contient la dernière ligne valide (1093)
Déjà je retrouve bien mon total de paires valides, c'est bon signe. Reste à s'assurer que tout est bien placé.
Il me reste la partie des anos.
J'ai préféré la prévoir dans un autre tableau, je pense que ça aurait pollué tes résultats intéressants.
Est-ce que 3 compteurs 1 frame, 3 frames, 4 frames est suffisant ou tu préfères le détail par nb frames/Class ?
eric
Bonjour eriiic, miro
Comme tu le soulignes, il faut passer par un traitement intermédiaire pour déterminer les directions
Le tableau source est restitué en feuil3 épuré des colonnes inutiles, une colonne supplémentaire a été rajoutée, les différentes directions y sont définies.
A partir de là, on peut utiliser un TCD je pense, mais je ne sais pas faire
A préalable, il faut créer la Feuil3 : feuille de restitution
Option Explicit
Sub test()
Dim a, liste, i As Long, valMin As Long, valMax As Long, pos, posMin As Byte, posMax As Byte
Dim sens As String
Application.ScreenUpdating = False
liste = Array(Array("Nord vers Ouest", "C2_FrameNord vers C3_FrameOuest"), _
Array("Nord vers Sud", "C2_FrameNord vers C4_FrameSud"), _
Array("Nord vers Est", "C2_FrameNord vers C1_FrameEst"), _
Array("Est vers Nord", "C1_FrameEst vers C2_FrameNord"), _
Array("Est vers Ouest", "C1_FrameEst vers C3_FrameOuest"), _
Array("Est vers Sud", "C1_FrameEst vers C4_FrameSud"), _
Array("Sud vers Est", "C4_FrameSud vers C1_FrameEst"), _
Array("Sud vers Nord", "C4_FrameSud vers C2_FrameNord"), _
Array("Sud vers Ouest", "C4_FrameSud vers C3_FrameOuest"), _
Array("Ouest vers Sud", "C3_FrameOuest vers C4_FrameSud"), _
Array("Ouest vers Est", "C3_FrameOuest vers C1_FrameEst"), _
Array("Ouest vers Nord", "C3_FrameOuest vers C2_FrameNord"))
With Sheets("1675_output").Range("A1").CurrentRegion
a = Application.Index(.Value, Evaluate("row(1:" & _
.Rows.Count & ")"), Array(2, 4, 8, 12, 17, 22, 27))
ReDim Preserve a(1 To UBound(a, 1), 1 To UBound(a, 2) + 1)
a(1, UBound(a, 2)) = "Direction"
For i = 2 To UBound(a, 1)
valMin = Application.Min(Application.Index(a, i, [transpose(row(4:7))]))
valMax = Application.Max(Application.Index(a, i, [transpose(row(4:7))]))
posMin = Application.Match(valMin, Application.Index(a, i, [transpose(row(1:7))]), 0)
posMax = Application.Match(valMax, Application.Index(a, i, [transpose(row(1:7))]), 0)
sens = a(1, posMin) & " vers " & a(1, posMax)
pos = Application.Match(sens, Application.Index(liste, 0, 2), 0)
If Not IsError(pos) Then
a(i, UBound(a, 2)) = liste(pos - 1)(0)
End If
Next
End With
'restitution en Feuil3
With Sheets("Feuil3").Range("A1")
.CurrentRegion.Clear
With .Resize(UBound(a, 1), UBound(a, 2))
.FormulaLocal = a
.Font.Name = "calibri"
.Font.Size = 10
.VerticalAlignment = xlCenter
.BorderAround Weight:=xlThin
.Borders(xlInsideVertical).Weight = xlThin
.Columns(.Columns.Count).HorizontalAlignment = xlCenter
With .Rows(1)
.HorizontalAlignment = xlCenter
.BorderAround Weight:=xlThin
.Interior.ColorIndex = 40
End With
.Columns.ColumnWidth = 15
End With
End With
Application.ScreenUpdating = True
End SubLe traitement est un peu long
klin89
comme on a changé de page je précise que tu as une proposition et une question à mon post précédent.
eric
edit :
à la réflexion, pour les anos je pense que 3 compteurs suffisent. En avoir 3x6=18 avec beaucoup à 0 ne sera pas bien utile.
Je vois ça un peu plus tard
Re miro,
Essaie ceci :
A préalable, crée la Feuil3 soit la feuille de restitution
Option Explicit
Sub test()
Dim a, w(), liste, e, i As Long, j As Long, n As Long, valMin As Long, valMax As Long
Dim sens As String, pos, posMin As Byte, posMax As Byte
Dim dico As Object, dico1 As Object, dico2 As Object
Set dico = CreateObject("Scripting.Dictionary"): dico.CompareMode = 1
Set dico1 = CreateObject("Scripting.Dictionary"): dico1.CompareMode = 1
Set dico2 = CreateObject("Scripting.Dictionary"): dico2.CompareMode = 1
liste = Array(Array("Nord vers Ouest", "C2_FrameNord vers C3_FrameOuest"), _
Array("Nord vers Sud", "C2_FrameNord vers C4_FrameSud"), _
Array("Nord vers Est", "C2_FrameNord vers C1_FrameEst"), _
Array("Est vers Nord", "C1_FrameEst vers C2_FrameNord"), _
Array("Est vers Ouest", "C1_FrameEst vers C3_FrameOuest"), _
Array("Est vers Sud", "C1_FrameEst vers C4_FrameSud"), _
Array("Sud vers Est", "C4_FrameSud vers C1_FrameEst"), _
Array("Sud vers Nord", "C4_FrameSud vers C2_FrameNord"), _
Array("Sud vers Ouest", "C4_FrameSud vers C3_FrameOuest"), _
Array("Ouest vers Sud", "C3_FrameOuest vers C4_FrameSud"), _
Array("Ouest vers Est", "C3_FrameOuest vers C1_FrameEst"), _
Array("Ouest vers Nord", "C3_FrameOuest vers C2_FrameNord"))
For Each e In liste
dico1(e(0)) = dico1.Count + 2
Next
For Each e In Array("car", "cyclist", "hgv", "lgv", "motorbike", "pedestrian")
dico2(e) = dico2.Count + 2
Next
With Sheets("1675_output").Range("A1").CurrentRegion
a = Application.Index(.Value, Evaluate("row(1:" & _
.Rows.Count & ")"), Array(2, 4, 8, 12, 17, 22, 27))
ReDim Preserve a(1 To UBound(a, 1), 1 To UBound(a, 2) + 1)
a(1, UBound(a, 2)) = "Direction"
For i = 2 To UBound(a, 1)
valMin = Application.Min(Application.Index(a, i, [transpose(row(4:7))]))
valMax = Application.Max(Application.Index(a, i, [transpose(row(4:7))]))
posMin = Application.Match(valMin, Application.Index(a, i, [transpose(row(1:7))]), 0)
posMax = Application.Match(valMax, Application.Index(a, i, [transpose(row(1:7))]), 0)
sens = a(1, posMin) & " vers " & a(1, posMax)
pos = Application.Match(sens, Application.Index(liste, 0, 2), 0)
If Not IsError(pos) Then
a(i, UBound(a, 2)) = liste(pos - 1)(0)
End If
If Not IsEmpty(a(i, 8)) Then
If Not dico.exists(a(i, 2)) Then
ReDim w(1 To dico1.Count + 1, 1 To dico2.Count + 1)
w(1, 1) = a(i, 2)
For j = 0 To dico1.Count - 1
w(j + 2, 1) = dico1.keys()(j)
Next
For j = 0 To dico2.Count - 1
w(1, j + 2) = dico2.keys()(j)
Next
End If
w(dico1(a(i, 8)), dico2(a(i, 3))) = w(dico1(a(i, 8)), dico2(a(i, 3))) + 1
dico(a(i, 2)) = w
End If
Next
End With
'restitution en Feuil3
Application.ScreenUpdating = False
With Sheets("Feuil3")
.UsedRange.Clear
With .Range("a1")
For i = 0 To dico.Count - 1
With .Offset(n)
With .Resize(UBound(dico.items()(i), 1), UBound(dico.items()(i), 2))
.Value = Application.Transpose(Application.Transpose(dico.items()(i)))
.BorderAround Weight:=xlThin
.Borders(xlInsideVertical).Weight = xlThin
With .Rows(1)
.HorizontalAlignment = xlCenter
.BorderAround Weight:=xlThin
With .Offset(, 1).Resize(, .Columns.Count - 1)
.Interior.ColorIndex = 15
End With
End With
With .Columns(1)
With .Offset(1).Resize(.Rows.Count - 1)
.Interior.ColorIndex = 19
End With
End With
End With
End With
n = n + UBound(dico.items()(i), 1) + 1
Next
End With
With .UsedRange
.Font.Name = "calibri"
.Font.Size = 10
.VerticalAlignment = xlCenter
With .Columns(1)
.HorizontalAlignment = xlCenter
.ColumnWidth = 17
End With
End With
.Activate
End With
Set dico = Nothing: Set dico1 = Nothing: Set dico2 = Nothing
Application.ScreenUpdating = True
End Subklin89
Bonjour Messieurs
Merci bcp
Je regarde tout cela attentivement en fin d'après-midi
Bonne journée
eriiic a écrit :Bonjour,
un peu plus compliqué que ce que je pensais.
Voilà le début que tu commences les contrôles (une horreur
). Je n'ai contrôlé que Est vers Ouest et Ouest vers Est du 1er 1/4h.
Si tu pouvais en contrôler un plus pour valider, en priorité celui qui contient la dernière ligne valide (1093)
Déjà je retrouve bien mon total de paires valides, c'est bon signe. Reste à s'assurer que tout est bien placé.
Il me reste la partie des anos.
J'ai préféré la prévoir dans un autre tableau, je pense que ça aurait pollué tes résultats intéressants.
Est-ce que 3 compteurs 1 frame, 3 frames, 4 frames est suffisant ou tu préfères le détail par nb frames/Class ?
eric
Bonjour Eric
Je viens de contrôler et tout m'a l'air nickel
Les anos imppec aussi
Merci bcp de votre aide, ce fichier répond entièrement à ma demande.
Je vais pouvoir comparer ces résultats à ceux que j'avais déjà via une autre source
Je vais essayer de comprendre le code pour pouvoir l'appliquer sur des situations similaires avec +/- 1 branche
Encore merci