无法将元组添加到BlockingCollection:C#中的错误CS1503。

huangapple go评论74阅读模式
英文:

Cannot Add Tuple to BlockingCollection: Error CS1503 in C#

问题

I'm working on a project that involves object detection with real-time video in C#. As part of the project, I use a BlockingCollection to manage a list of bounding boxes for detected objects, and the details for each bounding box are held in a tuple. However, I'm encountering an error CS1503 when trying to add new tuples to the collection. Here's how I defined the BlockingCollection:

BlockingCollection<Tuple<int, int, int, int, string, string, Scalar, DateTime>> ObjectDetectionBbox = new BlockingCollection<Tuple<int, int, int, int, string, string, Scalar, DateTime>>();

And here's the line where I'm trying to add a new tuple to the collection:

ObjectDetectionBbox.Add(Tuple.Create(
    topLeft.X,                        
    topLeft.Y,                        
    bottomRight.X - topLeft.X,        
    bottomRight.Y - topLeft.Y,        
    className,                        
    trackedName,                      
    classColor,                       
    bboxTimestamp                     
));

The error message is:

Error CS1503 Argument 1: cannot convert from 'System.Tuple<int, int, int, int, string, string, OpenCvSharp.Scalar, System.Tuple<System.DateTime>>' to 'System.Tuple<int, int, int, int, string, string, OpenCvSharp.Scalar, System.DateTime>'

The error message seems to suggest that my tuple has a Tuple as the last element, but as you can see in my code, the last element is a DateTime.

I've confirmed that bboxTimestamp is indeed a DateTime, and I'm not sure why this error is happening.

英文:

I'm working on a project that involves object detection with real-time video in C#. As part of the project, I use a BlockingCollection to manage a list of bounding boxes for detected objects, and the details for each bounding box are held in a tuple. However, I'm encountering an error CS1503 when trying to add new tuples to the collection. Here's how I defined the BlockingCollection:

BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt; ObjectDetectionBbox = new BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt;();

And here's the line where I'm trying to add a new tuple to the collection:

ObjectDetectionBbox.Add(Tuple.Create(
    topLeft.X,                        
    topLeft.Y,                        
    bottomRight.X - topLeft.X,        
    bottomRight.Y - topLeft.Y,        
    className,                        
    trackedName,                      
    classColor,                       
    bboxTimestamp                     
));

The error message is:

> Error CS1503 Argument 1: cannot convert from 'System.Tuple<int, int, int, int, string, string, OpenCvSharp.Scalar, System.Tuple<System.DateTime>>' to 'System.Tuple<int, int, int, int, string, string, OpenCvSharp.Scalar, System.DateTime>'

The error message seems to suggest that my tuple has a Tuple<DateTime> as the last element, but as you can see in my code, the last element is a DateTime.

I've confirmed that bboxTimestamp is indeed a DateTime, and I'm not sure why this error is happening.
无法将元组添加到BlockingCollection:C#中的错误CS1503。

无法将元组添加到BlockingCollection:C#中的错误CS1503。

Does anyone know why this might be happening and how I could fix it? Any help would be greatly appreciated.

HERE IS THE FULL CODE FOR REFERENCE:

public async Task Main(System.Windows.Controls.Image imageControl, CancellationToken token)
{
BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt; ObjectDetectionBbox = new BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt;();
BlockingCollection&lt;Tuple&lt;Mat, DateTime&gt;&gt; frameBuffer = new BlockingCollection&lt;Tuple&lt;Mat, DateTime&gt;&gt;(); // Our new frame buffer
string cameraUrl = &quot;http://cam1.infolink.ru/mjpg/video.mjpg&quot;;
//string cameraUrl = &quot;http://hotel-seerose.dyndns.org:8001/cgi-bin/faststream.jpg?stream=full&amp;fps=0&quot;;
string URLreturnBbox = &quot;http://localhost:8003/api/v1/camera/get_frame&quot;;  // Updated endpoint URL
await initializeRunServer(cameraUrl);
var idFaceDictionary = new ConcurrentDictionary&lt;long, object&gt;();
var classNames = await GetClassNames();
var colorList = InitColorList(classNames.Count);
Task processFrameTask = Task.Run(() =&gt; ProcessTask(imageControl, token, URLreturnBbox, classNames, colorList,idFaceDictionary, ObjectDetectionBbox));
// Create video source
MJPEGStream stream = new MJPEGStream(cameraUrl);
// New frame event handler
stream.NewFrame += (sender, eventArgs) =&gt;
{
// Convert AForge.NET&#39;s Bitmap to OpenCvSharp&#39;s Mat
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone();
Mat frame = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
// Get bbox info from ObjectDetectionBbox, if any
while (ObjectDetectionBbox.TryTake(out var bbox)) // Replace if with while to draw all available bounding boxes
{
// Ensure we only proceed if there is a detection and a valid class name.
if (!string.IsNullOrEmpty(bbox.Item5))
{
if (bbox.Item5 == &quot;person&quot; &amp;&amp; bbox.Item6 != null) // Display if person is detected
{
DrawPerson(
frame,
bbox.Item1,
bbox.Item2,
bbox.Item3,
bbox.Item4,
bbox.Item6,
bbox.Item7
);
}
else
{
Cv2.Rectangle(frame, new OpenCvSharp.Point(bbox.Item1, bbox.Item2), new OpenCvSharp.Point(bbox.Item1 + bbox.Item3, bbox.Item2 + bbox.Item4), bbox.Item7, 1);
var caption = bbox.Item5;
Cv2.PutText(frame, caption, new OpenCvSharp.Point(bbox.Item1, bbox.Item2), HersheyFonts.HersheyComplex, 1, bbox.Item7, 1);
}
}
}
// Process and display the frame
Application.Current.Dispatcher.Invoke(() =&gt;
{
UpdateDisplay(frame, imageControl);
});
};
// Start video capture
stream.Start();
// Wait until cancellation is requested
while (!token.IsCancellationRequested)
{
await Task.Delay(20);
}
// Stop video capture
stream.SignalToStop();
stream.WaitForStop();
}
public async Task ProcessTask(System.Windows.Controls.Image imageControl, CancellationToken token, string URLreturnBbox, IDictionary&lt;int, string&gt; classNames, List&lt;Scalar&gt; colorList, ConcurrentDictionary&lt;long, object&gt; idFaceDictionary, BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt; ObjectDetectionBbox)
{
while (!token.IsCancellationRequested)
{
if (RunOTModel &amp;&amp; ObjectTracking)
{
await GetObjectDetectionBbox(URLreturnBbox, classNames, colorList, idFaceDictionary, ObjectDetectionBbox);
}
}
}
private async Task GetObjectDetectionBbox(string boundingBoxesUrl, IDictionary&lt;int, string&gt; classNames, List&lt;Scalar&gt; colorList, ConcurrentDictionary&lt;long, object&gt; idFaceDictionary, BlockingCollection&lt;Tuple&lt;int, int, int, int, string, string, Scalar, DateTime&gt;&gt; ObjectDetectionBbox)
{
var resultsList = await RunYolo(boundingBoxesUrl);
// New dictionary to keep track of names already assigned
var assignedNames = new ConcurrentDictionary&lt;string, object&gt;();
foreach (var results in resultsList)
{
if (!results.ContainsKey(&quot;class_&quot;)) continue;
var classIndex = int.Parse(results[&quot;class_&quot;].ToString());
var className = classNames[classIndex];
var classColor = colorList[classIndex];
var topLeft = new OpenCvSharp.Point((long)results[&quot;x&quot;], (long)results[&quot;y&quot;]);
var bottomRight = new OpenCvSharp.Point((long)results[&quot;w&quot;], (long)results[&quot;h&quot;]);
string trackedName = null;
long trackId = 0; // initialize with default value
bool hasTrackId = results.ContainsKey(&quot;track_id&quot;);
DateTime bboxTimestamp = DateTime.Parse(results[&quot;timestamp&quot;].ToString());
if (hasTrackId)
{
trackId = (long)results[&quot;track_id&quot;];
}
if (OTFaceRecognition &amp;&amp; hasTrackId &amp;&amp; className == &quot;person&quot; &amp;&amp; !idFaceDictionary.ContainsKey(trackId))
{
if (results.ContainsKey(&quot;result&quot;) &amp;&amp; results[&quot;result&quot;] != null)
{
var resultStr = results[&quot;result&quot;].ToString();
// Check if this name has not been assigned already
if (!string.IsNullOrEmpty(resultStr) &amp;&amp; !assignedNames.ContainsKey(resultStr))
{
// Remove any existing entries with the same value
foreach (var kvp in idFaceDictionary.Where(kvp =&gt; kvp.Value.Equals(resultStr)).ToList())
{
idFaceDictionary.TryRemove(kvp.Key, out _);
}
// Add the new entry
idFaceDictionary.TryAdd(trackId, resultStr);
// Add this name to the assigned names
assignedNames[resultStr] = new object();
}
}
}
if (OTFaceRecognition &amp;&amp; hasTrackId)
{
trackedName = idFaceDictionary.ContainsKey(trackId)
? $&quot;{idFaceDictionary[trackId]} - ID {results[&quot;track_id&quot;]}&quot;
: null;
}
ObjectDetectionBbox.Add(Tuple.Create(
topLeft.X,                        // int
topLeft.Y,                        // int
bottomRight.X - topLeft.X,        // int
bottomRight.Y - topLeft.Y,        // int
className,                        // string
trackedName,                      // string
classColor,                       // Scalar
bboxTimestamp                     // DateTime
));
}
}

答案1

得分: 3

Tuple.Create&lt;T1,T2,T3,T4,T5,T6,T7,T8&gt;(T1, T2, T3, T4, T5, T6, T7, T8) 的返回类型如下:

Tuple&lt;T1,T2,T3,T4,T5,T6,T7,Tuple&lt;T8&gt;&gt;

所以最后一个元素不是类型,而是单一元组,因此会出现错误。最小可重现示例如下:

Tuple&lt;int, int, int, int, string, string, double, DateTime&gt; tup 
  = Tuple.Create(1, 1, 1, 1, &quot;&quot;, &quot;&quot;, 2.0, DateTime.UtcNow);

您可以直接使用 Tuple 的构造函数:

Tuple&lt;int, int, int, int, string, string, double, DateTime&gt; tup 
    = new Tuple&lt;int, int, int, int, string, string, double, DateTime&gt;(1, 1, 1, 1, &quot;&quot;, &quot;&quot;, 2.0, DateTime.UtcNow);

但一般来说,我建议避免使用元组来表示这样数量多的项 - 最好引入一个类/结构体/记录。

英文:

Tuple.Create&lt;T1,T2,T3,T4,T5,T6,T7,T8&gt;(T1, T2, T3, T4, T5, T6, T7, T8) has the following return type:

Tuple&lt;T1,T2,T3,T4,T5,T6,T7,Tuple&lt;T8&gt;&gt;

So the last element is not the the type but tuple of single hence the error. Minimal reproducible example would be something like the following:

Tuple&lt;int, int, int, int, string, string, double, DateTime&gt; tup 
  = Tuple.Create(1, 1, 1, 1, &quot;&quot;, &quot;&quot;, 2.0, DateTime.UtcNow);

You can use the ctor for Tuple directly:

Tuple&lt;int, int, int, int, string, string, double, DateTime&gt; tup 
    = new Tuple&lt;int, int, int, int, string, string, double, DateTime&gt;(1, 1, 1, 1, &quot;&quot;, &quot;&quot;, 2.0, DateTime.UtcNow);

But in general I would recommend to avoid using tuples for such "big" number of items - just introduce a class/struct/record.

huangapple
  • 本文由 发表于 2023年6月29日 04:59:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576671.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定