У меня есть следующий код C#, который я хочу преобразовать в VB.NET:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using OpenCvSharp;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string sPath = "c:\\users\\myuser\\desktop\\lenna.png";
using (var src = new Mat(sPath, ImreadModes.Color))
using (var srcGray = new Mat(sPath, ImreadModes.GrayScale))
using (var hsv = new Mat())
using (var dst = new Mat())
{
Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);
Cv2.CvtColor(srcGray, dst, ColorConversionCodes.GRAY2BGR);
var hsvChannels = Cv2.Split(hsv);
var v = hsvChannels[2];
for (int i = 0; i < 8; i++)
{
using (var bin = new Mat())
{
Cv2.Threshold(v, bin, i * 32, 255, ThresholdTypes.Tozero);
Cv2.Threshold(bin, bin, (i + 1) * 32, 255, ThresholdTypes.BinaryInv);
Cv2.FindContours(bin, out var contours, out _, RetrievalModes.External,
ContourApproximationModes.ApproxNone);
Cv2.DrawContours(dst, contours, -1, Scalar.Red, 1);
}
}
Window.ShowImages(dst);
foreach (var m in hsvChannels)
m.Dispose();
}
}
}
}
Мне удалось преобразовать его, но "_" вызывает у меня головную боль.
Компилятор говорит мне «Не самый конкретный», если я заменяю его на «Ничего».
И если я объявляю такие «контуры» (чтобы быть более конкретными), компилятор сообщает мне, что «Ничего» - недопустимый аргумент:
Dim contours As OpenCvSharp.Mat()
Вот моя попытка VB.NET:
Imports OpenCvSharp
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim sPath As String = "c:\users\myuser\desktop\lenna.png"
Using src = New Mat(sPath, ImreadModes.Color)
Using srcGray = New Mat(sPath, ImreadModes.GrayScale)
Using hsv = New OpenCvSharp.Mat()
Using dst = New Mat()
Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV)
Cv2.CvtColor(srcGray, dst, ColorConversionCodes.GRAY2BGR)
Dim hsvChannels = Cv2.Split(hsv)
Dim v = hsvChannels(2)
For i As Integer = 0 To 7
Using bin = New Mat()
Cv2.Threshold(v, bin, i * 32, 255, ThresholdTypes.Tozero)
Cv2.Threshold(bin, bin, (i + 1) * 32, 255, ThresholdTypes.BinaryInv)
Dim contours
Cv2.FindContours(bin, contours, Nothing, RetrievalModes.External, ContourApproximationModes.ApproxNone) // Compiler error occurs here
Cv2.DrawContours(dst, contours, -1, Scalar.Red, 1)
End Using
Next i
Window.ShowImages(dst)
For Each m In hsvChannels
m.Dispose()
Next m
End Using
End Using
End Using
End Using
End Sub
End Class
Я не уверен, что компилятор хочет от меня. Кто-нибудь знает? Использование подчеркивания или двойного подчеркивания (как предлагают некоторые онлайн-конвертеры) не сработает.
Это объявления FindContours:
Public Shared Sub FindContours(image As InputOutputArray, ByRef contours() As Mat, hierarchy As OutputArray, mode As RetrievalModes, method As ContourApproximationModes, Optional offset As Point? = Nothing)
Public Shared Sub FindContours(image As InputOutputArray, ByRef contours As Point()(), ByRef hierarchy() As HierarchyIndex, mode As RetrievalModes, method As ContourApproximationModes, Optional offset As Point? = Nothing)





Аргумент подчеркивания в C# - это отказаться. Насколько мне известно, VB не имеет аналогов. Поскольку это параметр out, вам необходимо объявить локальную фиктивную переменную и передать ее:
Dim contours As Point()()
Dim unused As HierarchyIndex()
Cv2.FindContours(bin, contours, unused, RetrievalModes.External, ContourApproximationModes.ApproxNone)
Также обратите внимание, что в вашем локальном объявлении contours отсутствует тип и поэтому он неполный. Компилятор должен отклонить это как недопустимое (если вы компилируете с Option Strict, что и должно быть).
@tmighty Спасибо, я указал неправильный тип. Я починил, теперь должно работать.
Компилятор сообщает мне, что для этих аргументов нет перегрузок.
@tmighty Ух, попробуйте еще раз. Я снова напортачил. Тем не менее, опубликованное вами объявление немного странно, поскольку параметр не объявлен как ByRef (out в C#), поэтому это не должно работать - или, по крайней мере, это не эквивалентно коду C#.
Теперь он сообщает мне: «Ошибка перегрузки, так как New недоступен». Я также пробовал «Dim unused = New OpenCvSharp.OutputArray ()», но это дает тот же результат.
@tmighty ОК, попробуйте другую перегрузку (contours As Point()() и unused as HierarchyIndex()). Мы доберемся туда! К сожалению, у меня нет компилятора VB для проверки синтаксиса объявлений, но он должен работать.
Вот и получилось !! Большое спасибо!!
Компилятор не знает, какую перегрузку вы хотите использовать, потому что вы не указали тип для contours. Укажите тип contours: Dim contours as Point() или Dim contours as Mat.
Подчеркивание _ используется в csharp, когда вас не интересует значение параметра. Поскольку VB не имеет механизма вывода, вы должны указать временную переменную для аргумента подчеркивания Dim hierarchy() As HierarchyIndex или Dim hierarchy As OutputArray.
При использовании VB.net убедитесь, что вы указали типы параметров - и, если возможно, включите строгую проверку типов. Это заставляет вас писать более чистый код, более безопасный по типу. Это избавит вас от многих головных болей.
Я сделал это, как вы предложили, и дополнительно объявил «Dim contours () As OpenCvSharp.Mat», однако компилятор сообщает мне «NullException: иерархия Parametername не может быть NULL».