static void ProcessOutput(int levelNr, ReadOnlySpan <int> resultDims, float[] tensorData, ArrayList dets) { int boxStride = resultDims[2] * resultDims[3] * resultDims[4]; for (int boxNr = 0; boxNr < resultDims[1]; boxNr++) { for (int gridY = 0; gridY < resultDims[2]; gridY++) { for (int gridX = 0; gridX < resultDims[3]; gridX++) { var bx = (Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4]]) * 2 - 0.5f + gridX) * scales[levelNr]; var by = (Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4] + 1]) * 2 - 0.5f + gridY) * scales[levelNr]; var bw = (float)SQR(Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4] + 2]) * 2) * anchorLevels[levelNr, boxNr, 0]; var bh = (float)SQR(Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4] + 3]) * 2) * anchorLevels[levelNr, boxNr, 1]; var obj = Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4] + 4]); var classScr = Sigmoid(tensorData[boxNr * boxStride + (gridX + gridY * resultDims[3]) * resultDims[4] + 5]); if (obj * classScr > SCORETHRESHOLD) { DetRect det = new DetRect(); det.m_x1 = bx - 0.5f * bw; det.m_x2 = bx + 0.5f * bw; det.m_y1 = by - 0.5f * bh; det.m_y2 = by + 0.5f * bh; det.m_score = obj * classScr; dets.Add(det); } } } } }
public DetRect Intersect(DetRect other) { DetRect inter = new DetRect(); inter.m_x1 = this.m_x1 > other.m_x1 ? this.m_x1 : other.m_x1; inter.m_y1 = this.m_y1 > other.m_y1 ? this.m_y1 : other.m_y1; inter.m_x2 = this.m_x2 < other.m_x2 ? this.m_x2 : other.m_x2; inter.m_y2 = this.m_y2 < other.m_y2 ? this.m_y2 : other.m_y2; return(inter); }
static ArrayList BuildFinalOutput(ArrayList dets, float scaleFactor, int offsetX, int offsetY) { ArrayList filteredRects = new ArrayList(); for (int n = 0; n < dets.Count; n++) { bool survived = true; DetRect cur = (DetRect)dets[n]; for (int n1 = n + 1; n1 < dets.Count; n1++) { DetRect other = (DetRect)dets[n1]; DetRect intersect = other.Intersect(cur); var interArea = intersect.Area(); var IoU = interArea / other.Area(); if (IoU > IoUTHRESHOLD) { survived = false; break; } } if (survived) { filteredRects.Add(cur); } } // project back into original image size for (int n = 0; n < filteredRects.Count; n++) { DetRect rect = (DetRect)filteredRects[n]; rect.m_x1 = (rect.m_x1 - offsetX) * (float)scaleFactor; rect.m_x2 = (rect.m_x2 - offsetX) * (float)scaleFactor; rect.m_y1 = (rect.m_y1 - offsetY) * (float)scaleFactor; rect.m_y2 = (rect.m_y2 - offsetY) * (float)scaleFactor; } return(filteredRects); }
public bool IsInside(DetRect other) { return(other.m_x1 >= this.m_x1 && other.m_x2 <= this.m_x2 && other.m_y1 >= this.m_y1 && other.m_y2 <= this.m_y2); }
static void DrawRectangle(DetRect rect, byte[] buffer, int lineWidth, int imgWidth, int imgHeight, int imgStride, int nChannels) { int startX = (int)rect.m_x1; if (startX < 0) { startX = 0; } int endX = (int)rect.m_x2; if (endX > imgWidth - 1) { endX = imgWidth - 1; } int startY = (int)rect.m_y1; if (startY < 0) { startY = 0; } int endY = (int)rect.m_y2; if (endY > imgHeight - 1) { endY = imgHeight - 1; } for (int line = 0; line < lineWidth; line++) { int yPos = startY + line; if (yPos >= 0 && yPos < imgHeight - 1) { for (int x = startX; x <= endX; x++) { buffer[x * nChannels + yPos * imgStride] = 0; buffer[x * nChannels + yPos * imgStride + 1] = 255; buffer[x * nChannels + yPos * imgStride + 2] = 0; } } yPos = endY + line; if (yPos >= 0 && yPos < imgHeight - 1) { for (int x = startX; x <= endX; x++) { buffer[x * nChannels + yPos * imgStride] = 0; buffer[x * nChannels + yPos * imgStride + 1] = 255; buffer[x * nChannels + yPos * imgStride + 2] = 0; } } int xPos = startX + line; if (xPos >= 0 && xPos < imgWidth - 1) { for (int y = startY; y <= endY; y++) { buffer[xPos * nChannels + y * imgStride] = 0; buffer[xPos * nChannels + y * imgStride + 1] = 255; buffer[xPos * nChannels + y * imgStride + 2] = 0; } } xPos = endX + line; if (xPos >= 0 && xPos < imgWidth - 1) { for (int y = startY; y <= endY; y++) { buffer[xPos * nChannels + y * imgStride] = 0; buffer[xPos * nChannels + y * imgStride + 1] = 255; buffer[xPos * nChannels + y * imgStride + 2] = 0; } } } }