最近公司須要開發一個DataMatrix碼識別的小軟件,因爲DataMatrix碼實在過小了網上找了不少案例都不能一會兒就識別多個二維碼。因此就只能經過OpenCvSharp來完成一系列的操做。code
下面直接上代碼,功能代碼都寫好註釋,不明白的地方能夠@我圖片
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
Mat srcImage = new Mat(openFileDialog.FileName);
//轉化爲灰度圖
Mat src_gray = new Mat();
//濾波
Cv2.Blur(srcImage, src_gray, new OpenCvSharp.Size(3, 3));
// Cv2.ImShow("濾波", src_gray);
Mat src_gray1 = new Mat();
//二值化 130 具體指能夠根據DataMatrix碼的白色的RGB值來調整
Cv2.Threshold(src_gray, src_gray1, 130, 255, ThresholdTypes.Binary);
//Cv2.ImShow("二值化", src_gray1);
//Canny邊緣檢測
Mat canny_Image = new Mat();
Cv2.Canny(src_gray1, canny_Image, 100, 200);
//Cv2.ImShow("Canny邊緣檢測", canny_Image);
//消除裂縫2 Size(11, 12) Size的值能夠調整,結果出來爲DataMatrix碼 區域全白就ok啦。
OpenCvSharp.Size size2 = new OpenCvSharp.Size(11, 12);
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, size2);
Cv2.MorphologyEx(canny_Image, canny_Image, MorphTypes.Close, kernel);
// Cv2.MorphologyEx(canny_Image, canny_Image, MorphTypes.Close, canny_Image1, null,6 , BorderTypes.Constant,1);
//Cv2.ImShow("消除裂縫", canny_Image);
//canny_Image.SaveImage("10.bmp");
//得到輪廓
Mat[] contours = new Mat[10000];
contours = Cv2.FindContoursAsMat(canny_Image, RetrievalModes.CComp, ContourApproximationModes.ApproxNone, null);
// Cv2.FindContours(canny_Image, out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new Point(0, 0));ip
//將結果畫出並返回結果
Mat dst_Image = Mat.Zeros(canny_Image.Size(), srcImage.Type());開發
int z = 0;
for (int i = 0; i < contours.Length; i++)
{
Rect rect = Cv2.BoundingRect(contours[i]);
//只判斷DataMatrix碼的寬度才進入解析
if (rect.Width > 60 && rect.Height > 88 && rect.Width < 100 && rect.Height < 110)
{
//將DataMatrix碼範圍的框框裁剪出圖片
Rect rect1 = new Rect(rect.X, rect.Y, rect.Width, rect.Height);
//srcImage 爲原圖像 rect1 裁剪的範圍。
Mat RectMat = new Mat(srcImage, rect1);
Bitmap bitmap = BitmapConverter.ToBitmap(RectMat);
//將裁剪出來的圖片進行放大,若是不放大ZXing解析的結果就不理想。(會漏了好多DataMatrix碼)
OpenCvSharp.Size size = new OpenCvSharp.Size(bitmap.Width * 5, bitmap.Height * 5);
Mat SizeMat = new Mat();
Cv2.Resize(RectMat, SizeMat, size);
bitmap.Dispose();
Bitmap bitmap1 = BitmapConverter.ToBitmap(SizeMat);
//bitmap.Save(i + ".png");
for (int y = 0; y < 4; y++)
{
//解析DataMatrix碼
BarcodeReader reader = new BarcodeReader();
Result result = reader.Decode(bitmap1);
if (result == null)
{
//翻轉圖片讓ZXing從新解析,防止DataMatrix碼由於位置識別不出來
bitmap1.RotateFlip(RotateFlipType.Rotate90FlipNone);
continue;
}
else
{
z++;
bitmap1.Save(z + ".jpg");
textBox1.Text += "第" + z + "個碼:" + result.ToString() + Environment.NewLine;
break;
}
}it
bitmap1.Dispose();
RectMat.Dispose();
SizeMat.Dispose();
Scalar color = Scalar.Red;
Cv2.DrawContours(dst_Image, contours, i, color, 2, LineTypes.Link8, null);io
}軟件
}二維碼
srcImage.Dispose();
// Cv2.ImShow("結果", dst_Image);
dst_Image.SaveImage("1.bmp");
}map
//**我也是一個站在巨人肩旁寫程序的搬運工(前人種樹後人乘涼)**//程序