Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
ReelCounter
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 54f08551
由
cuiyadong
编写于
2019-04-25 17:42:26 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
获取元器件特征
1 个父辈
e7982bd2
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
314 行增加
和
98 行删除
AccImage/ImageUtil.cs
AccImage/SplitItem.cs
Demo/MainForm.cs
AccImage/ImageUtil.cs
查看文件 @
54f0855
...
@@ -207,11 +207,14 @@ namespace Acc.Img
...
@@ -207,11 +207,14 @@ namespace Acc.Img
{
{
Bitmap
bitmap
=
new
Bitmap
(
image
);
Bitmap
bitmap
=
new
Bitmap
(
image
);
Mat
imageMat
=
BitmapConverter
.
ToMat
(
bitmap
);
Mat
imageMat
=
BitmapConverter
.
ToMat
(
bitmap
);
RadiusPt
radiusPt
,
radiusPtOut
;
GetCenter
(
imageMat
,
out
radiusPt
);
GetOutContour
(
imageMat
,
out
radiusPtOut
);
Cv2
.
CvtColor
(
imageMat
,
imageMat
,
ColorConversionCodes
.
RGBA2BGR
);
Cv2
.
CvtColor
(
imageMat
,
imageMat
,
ColorConversionCodes
.
RGBA2BGR
);
Mat
grayMat
=
BitmapConverter
.
ToMat
(
bitmap
);
Mat
grayMat
=
BitmapConverter
.
ToMat
(
bitmap
);
Cv2
.
CvtColor
(
grayMat
,
grayMat
,
ColorConversionCodes
.
RGB2GRAY
);
Cv2
.
CvtColor
(
grayMat
,
grayMat
,
ColorConversionCodes
.
RGB2GRAY
);
CvBlobs
blobs
=
AutoThreshBlobs
(
ref
grayMat
,
itemArea
,
out
itemArea
);
CvBlobs
blobs
=
AutoThreshBlobs
(
ref
grayMat
,
itemArea
,
out
itemArea
,
radiusPt
,
radiusPtOut
);
int
totalCount
=
findCircles
(
ref
imageMat
,
grayMat
,
blobs
,
itemArea
);
int
totalCount
=
findCircles
(
ref
imageMat
,
grayMat
,
blobs
,
itemArea
,
radiusPt
,
radiusPtOut
);
//imageMat = grayMat;
//imageMat = grayMat;
//int totalCount = CountBlobs(blobs, itemArea, ref imageMat);
//int totalCount = CountBlobs(blobs, itemArea, ref imageMat);
image
=
BitmapConverter
.
ToBitmap
(
imageMat
);
image
=
BitmapConverter
.
ToBitmap
(
imageMat
);
...
@@ -442,8 +445,8 @@ namespace Acc.Img
...
@@ -442,8 +445,8 @@ namespace Acc.Img
}
}
private
static
CvBlobs
AutoThreshBlobs
(
ref
Mat
imageMat
,
int
blobArea
,
out
int
standArea
)
private
static
CvBlobs
AutoThreshBlobs
(
ref
Mat
imageMat
,
int
blobArea
,
out
int
standArea
,
RadiusPt
radiusPt
,
RadiusPt
radiusPtOut
)
{
{
Mat
[]
mats
=
new
Mat
[]
{
imageMat
};
//一张图片,初始化为panda
Mat
[]
mats
=
new
Mat
[]
{
imageMat
};
//一张图片,初始化为panda
Mat
hist
=
new
Mat
();
//用来接收直方图
Mat
hist
=
new
Mat
();
//用来接收直方图
int
[]
channels
=
new
int
[]
{
0
};
//一个通道,初始化为通道0
int
[]
channels
=
new
int
[]
{
0
};
//一个通道,初始化为通道0
...
@@ -682,17 +685,18 @@ namespace Acc.Img
...
@@ -682,17 +685,18 @@ namespace Acc.Img
//{
//{
// count = (int)Math.Round((blobArea + k * averageArea) / (k * averageArea));
// count = (int)Math.Round((blobArea + k * averageArea) / (k * averageArea));
//}
//}
//count = (int)((blobArea + k * averageArea) / (k * averageArea));
count
=
(
int
)((
blobArea
+
k
*
averageArea
)
/
(
k
*
averageArea
));
count
=
(
int
)((
blobArea
+
k
*
averageArea
)
/
(
k
*
averageArea
));
if
(
count
==
0
||
count
==
1
)
if
(
count
==
0
||
count
==
1
)
{
{
count
=
1
;
count
=
1
;
}
}
if
(
count
<=
5
000
)
//if (count <= 10
000)
{
//
{
return
count
;
return
count
;
}
//
}
return
0
;
//
return 0;
}
}
/// <summary>
/// <summary>
...
@@ -845,12 +849,10 @@ namespace Acc.Img
...
@@ -845,12 +849,10 @@ namespace Acc.Img
public
static
SplitItem
findCircleInBlob
(
double
[,]
matDistanceArr
,
CvBlobs
blobs
,
CvBlob
blob
,
Point2d
reelCenter
,
double
oneBlobWidth
=
-
1
,
double
oneBlobRadius
=
-
1
)
public
static
SplitItem
findCircleInBlob
(
double
[,]
matDistanceArr
,
CvBlobs
blobs
,
CvBlob
blob
,
Point2d
reelCenter
,
double
oneBlobWidth
=
-
1
,
double
oneBlobRadius
=
-
1
)
{
{
SplitItem
item
=
new
SplitItem
();
SplitItem
item
=
new
SplitItem
();
int
ct
=
0
;
while
(
true
)
while
(
true
)
{
{
bool
hasFind
=
false
;
bool
hasFind
=
false
;
bool
hasPixToHandle
=
false
;
bool
hasPixToHandle
=
false
;
ct
+=
1
;
for
(
int
x
=
blob
.
MinX
;
x
<
blob
.
MaxX
;
x
++)
for
(
int
x
=
blob
.
MinX
;
x
<
blob
.
MaxX
;
x
++)
{
{
for
(
int
y
=
blob
.
MinY
;
y
<
blob
.
MaxY
;
y
++)
for
(
int
y
=
blob
.
MinY
;
y
<
blob
.
MaxY
;
y
++)
...
@@ -891,16 +893,7 @@ namespace Acc.Img
...
@@ -891,16 +893,7 @@ namespace Acc.Img
hasFind
=
true
;
hasFind
=
true
;
break
;
break
;
}
}
}
}
else
{
if
(
ct
>
100
)
{
////hasFind = true;
hasPixToHandle
=
false
;
break
;
}
}
}
}
}
}
...
@@ -922,6 +915,85 @@ namespace Acc.Img
...
@@ -922,6 +915,85 @@ namespace Acc.Img
}
}
return
item
;
return
item
;
}
}
public
struct
CircleStruct
{
public
OpenCvSharp
.
Point
centerPt
;
public
double
radius
;
}
private
static
int
startI
=
-
1
;
private
static
List
<
CircleStruct
>
resultList
=
new
List
<
CircleStruct
>();
private
static
List
<
List
<
CircleStruct
>>
spitList
=
new
List
<
List
<
CircleStruct
>>();
private
static
CircleStruct
circleStruct
=
new
CircleStruct
();
public
static
void
findCircleInBlobNew
(
double
[,]
matDistanceArr
,
CvBlobs
blobs
,
CvBlob
blob
,
Point2d
reelCenter
,
double
oneBlobWidth
=
-
1
,
double
oneBlobRadius
=
-
1
)
{
resultList
.
Clear
();
for
(
int
x
=
blob
.
MinX
;
x
<
blob
.
MaxX
;
x
++)
{
for
(
int
y
=
blob
.
MinY
;
y
<
blob
.
MaxY
;
y
++)
{
double
distance
=
matDistanceArr
[
x
,
y
];
if
(
distance
>
0
)
{
int
label
=
blobs
.
GetLabel
(
x
,
y
);
if
(
label
!=
blob
.
Label
)
{
continue
;
}
else
{
if
(
distance
>=
oneBlobRadius
*
0.8
)
{
circleStruct
.
centerPt
.
X
=
x
;
circleStruct
.
centerPt
.
Y
=
y
;
circleStruct
.
radius
=
distance
;
if
(
startI
==
-
1
)
{
startI
=
1
;
resultList
.
Add
(
circleStruct
);
}
else
{
bool
intersectionB
=
false
;
foreach
(
CircleStruct
item
in
resultList
)
{
//if (Math.Abs(item.centerPt.DistanceTo(new OpenCvSharp.Point(reelCenter.X,reelCenter.Y))-circleStruct.centerPt.DistanceTo(new OpenCvSharp.Point(reelCenter.X, reelCenter.Y)))<=oneBlobWidth)
//{
// intersectionB = true;
// break;
//}
if
(
item
.
centerPt
.
DistanceTo
(
circleStruct
.
centerPt
)<
item
.
radius
+
distance
)
{
intersectionB
=
true
;
break
;
}
}
if
(!
intersectionB
)
{
resultList
.
Add
(
circleStruct
);
}
}
}
}
}
}
}
//分离
while
(
resultList
.
Count
!=
0
)
{
}
}
/// <summary>
/// <summary>
/// 查找Blobs包含的元器件数量
/// 查找Blobs包含的元器件数量
...
@@ -931,12 +1003,9 @@ namespace Acc.Img
...
@@ -931,12 +1003,9 @@ namespace Acc.Img
/// <param name="blobs"></param>
/// <param name="blobs"></param>
/// <param name="avgArea"></param>
/// <param name="avgArea"></param>
/// <returns></returns>
/// <returns></returns>
public
static
int
findCircles
(
ref
Mat
srcMat
,
Mat
threshMat
,
CvBlobs
blobs
,
int
avgArea
)
public
static
int
findCircles
(
ref
Mat
srcMat
,
Mat
threshMat
,
CvBlobs
blobs
,
int
avgArea
,
RadiusPt
radiusPt
,
RadiusPt
radiusPtOut
)
{
{
Mat
distanceMat
=
new
Mat
();
Mat
distanceMat
=
new
Mat
();
RediusPt
rediusPt
,
rediusPtOut
;
GetCenter
(
srcMat
,
out
rediusPt
);
GetOutContour
(
srcMat
,
out
rediusPtOut
);
Cv2
.
DistanceTransform
(
threshMat
,
distanceMat
,
DistanceTypes
.
L2
,
DistanceMaskSize
.
Mask3
);
Cv2
.
DistanceTransform
(
threshMat
,
distanceMat
,
DistanceTypes
.
L2
,
DistanceMaskSize
.
Mask3
);
double
[,]
distanceArr
=
new
double
[
threshMat
.
Cols
,
threshMat
.
Rows
];
double
[,]
distanceArr
=
new
double
[
threshMat
.
Cols
,
threshMat
.
Rows
];
...
@@ -947,19 +1016,10 @@ namespace Acc.Img
...
@@ -947,19 +1016,10 @@ namespace Acc.Img
{
{
Stopwatch
sw
=
new
Stopwatch
();
Stopwatch
sw
=
new
Stopwatch
();
sw
.
Start
();
sw
.
Start
();
for
(
int
y
=
0
;
y
<
threshMat
.
Rows
;
y
++)
for
(
int
y
=
0
;
y
<
threshMat
.
Rows
;
y
++)
{
{
for
(
int
x
=
0
;
x
<
threshMat
.
Cols
;
x
++){
for
(
int
x
=
0
;
x
<
threshMat
.
Cols
;
x
++)
{
float
*
dd
=
(
float
*)
distanceMat
.
Ptr
(
y
,
x
);
float
*
dd
=
(
float
*)
distanceMat
.
Ptr
(
y
,
x
);
distanceArr
[
x
,
y
]
=
dd
[
0
];
distanceArr
[
x
,
y
]
=
dd
[
0
];
//float atValue = distanceMat.At<float>(y, x);
//distanceArr[x, y] = atValue;
//if (atValue != dd[0])
//{
// Console.WriteLine("rho=" + dd[0].ToString() + " atValue=" + atValue);
//}
}
}
}
}
sw
.
Stop
();
sw
.
Stop
();
...
@@ -970,30 +1030,11 @@ namespace Acc.Img
...
@@ -970,30 +1030,11 @@ namespace Acc.Img
Console
.
WriteLine
(
"Start find reel center"
);
Console
.
WriteLine
(
"Start find reel center"
);
Point2d
reelCenter
=
new
Point2d
(
0
,
0
)
;
Point2d
reelCenter
=
new
Point2d
(
0
,
0
)
;
////查找中心
////查找中心
//foreach (CvBlob blob in blobs.Values)
reelCenter
.
X
=
radiusPtOut
.
pt
.
X
;
//{
reelCenter
.
Y
=
radiusPtOut
.
pt
.
Y
;
// int count = BlobHasItem(avgArea, blob);
srcMat
.
Line
(
new
OpenCvSharp
.
Point
(
radiusPtOut
.
pt
.
X
-
10
,
radiusPtOut
.
pt
.
Y
),
new
OpenCvSharp
.
Point
(
radiusPtOut
.
pt
.
X
+
10
,
radiusPtOut
.
pt
.
Y
),
Scalar
.
Blue
);
// if (count > 10 && reelCenter.X == 0)
srcMat
.
Line
(
new
OpenCvSharp
.
Point
(
radiusPtOut
.
pt
.
X
,
radiusPtOut
.
pt
.
Y
-
10
),
new
OpenCvSharp
.
Point
(
radiusPtOut
.
pt
.
X
,
radiusPtOut
.
pt
.
Y
+
10
),
Scalar
.
Blue
);
// {
// Point2d center = blob.Centroid;
// //中间的圆,查找圆心
// if (center.DistanceTo(new Point2d(srcMat.Cols / 2, srcMat.Rows / 2)) < 200)
// {
// reelCenter = center;
// srcMat.Line(new OpenCvSharp.Point(center.X - 10, center.Y), new OpenCvSharp.Point(center.X + 10, center.Y), Scalar.Blue);
// srcMat.Line(new OpenCvSharp.Point(center.X, center.Y - 10), new OpenCvSharp.Point(center.X, center.Y + 10), Scalar.Blue);
// break;
// }
// }
//}
reelCenter
.
X
=
rediusPtOut
.
pt
.
X
;
reelCenter
.
Y
=
rediusPtOut
.
pt
.
Y
;
srcMat
.
Line
(
new
OpenCvSharp
.
Point
(
rediusPtOut
.
pt
.
X
-
10
,
rediusPtOut
.
pt
.
Y
),
new
OpenCvSharp
.
Point
(
rediusPtOut
.
pt
.
X
+
10
,
rediusPtOut
.
pt
.
Y
),
Scalar
.
Blue
);
srcMat
.
Line
(
new
OpenCvSharp
.
Point
(
rediusPtOut
.
pt
.
X
,
rediusPtOut
.
pt
.
Y
-
10
),
new
OpenCvSharp
.
Point
(
rediusPtOut
.
pt
.
X
,
rediusPtOut
.
pt
.
Y
+
10
),
Scalar
.
Blue
);
Console
.
WriteLine
(
"Start find reel Max Radius, max Width"
);
Console
.
WriteLine
(
"Start find reel Max Radius, max Width"
);
//最大
//最大
double
maxRadius
=
0
;
double
maxRadius
=
0
;
...
@@ -1041,7 +1082,7 @@ namespace Acc.Img
...
@@ -1041,7 +1082,7 @@ namespace Acc.Img
if
(
count
==
1
)
if
(
count
==
1
)
{
{
//单个元器件
//单个元器件
if
(
blob
.
Centroid
.
DistanceTo
(
new
Point2d
(
r
ediusPt
.
pt
.
X
,
rediusPt
.
pt
.
Y
))
<
re
diusPt
.
radius
-
10
)
if
(
blob
.
Centroid
.
DistanceTo
(
new
Point2d
(
r
adiusPt
.
pt
.
X
,
radiusPt
.
pt
.
Y
))
<
ra
diusPt
.
radius
-
10
)
{
{
continue
;
continue
;
}
}
...
@@ -1053,7 +1094,7 @@ namespace Acc.Img
...
@@ -1053,7 +1094,7 @@ namespace Acc.Img
//if (count > 20)
//if (count > 20)
//{
//{
// //中间的圆,去除
// //中间的圆,去除
// if (blob.Centroid.DistanceTo(reelCenter) < r
e
diusPt.radius)
// if (blob.Centroid.DistanceTo(reelCenter) < r
a
diusPt.radius)
// {
// {
// continue;
// continue;
// }
// }
...
@@ -1062,11 +1103,11 @@ namespace Acc.Img
...
@@ -1062,11 +1103,11 @@ namespace Acc.Img
// // continue;
// // continue;
// //}
// //}
//}
//}
if
(
blob
.
Centroid
.
DistanceTo
(
new
Point2d
(
r
ediusPt
.
pt
.
X
,
rediusPt
.
pt
.
Y
))
<
re
diusPt
.
radius
-
10
)
if
(
blob
.
Centroid
.
DistanceTo
(
new
Point2d
(
r
adiusPt
.
pt
.
X
,
radiusPt
.
pt
.
Y
))
<
ra
diusPt
.
radius
-
10
)
{
{
continue
;
continue
;
}
}
//多个元器件,查找 所有圆
//
//
多个元器件,查找 所有圆
SplitItem
item
=
findCircleInBlob
(
distanceArr
,
blobs
,
blob
,
reelCenter
,
maxWidth
,
maxRadius
);
SplitItem
item
=
findCircleInBlob
(
distanceArr
,
blobs
,
blob
,
reelCenter
,
maxWidth
,
maxRadius
);
//对所有圆进行分组
//对所有圆进行分组
List
<
List
<
Circle
>>
groupCircles
=
item
.
groupCircles
(
maxWidth
,
maxRadius
,
reelCenter
);
List
<
List
<
Circle
>>
groupCircles
=
item
.
groupCircles
(
maxWidth
,
maxRadius
,
reelCenter
);
...
@@ -1111,7 +1152,7 @@ namespace Acc.Img
...
@@ -1111,7 +1152,7 @@ namespace Acc.Img
// Mat distanceMat = new Mat();
// Mat distanceMat = new Mat();
// Mat labels = new Mat() ;
// Mat labels = new Mat() ;
// Cv2.DistanceTransform(gray, distanceMat, DistanceTypes.L2, DistanceMaskSize.Mask3) ;
// Cv2.DistanceTransform(gray, distanceMat, DistanceTypes.L2, DistanceMaskSize.Mask3) ;
// Cv2.Normalize(distanceMat, gray, 0, 255, NormTypes.MinMax);
// Cv2.Normalize(distanceMat, gray, 0, 255, NormTypes.MinMax);
// gray.ConvertTo(gray, MatType.CV_8UC1);
// gray.ConvertTo(gray, MatType.CV_8UC1);
// Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Otsu);
// Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Otsu);
...
@@ -1221,6 +1262,89 @@ namespace Acc.Img
...
@@ -1221,6 +1262,89 @@ namespace Acc.Img
// //image = BitmapConverter.ToBitmap(dist);
// //image = BitmapConverter.ToBitmap(dist);
// //return image;
// //return image;
//}
//}
public
static
int
GetGrayValue
(
ref
Image
image
,
int
markX
,
int
markY
)
{
Mat
imageMat
=
BitmapConverter
.
ToMat
(
new
Bitmap
(
image
));
RadiusPt
radiusPt
,
radiusPtOut
;
GetCenter
(
imageMat
,
out
radiusPt
);
GetOutContour
(
imageMat
,
out
radiusPtOut
);
Mat
grayMat
=
new
Mat
();
Mat
thresholdMat
=
new
Mat
();
int
minThreshold
=
-
1
;
int
sampThreshold
=
-
1
,
blobNum
=
-
1
;
double
minArea
,
maxArea
,
proportion
=
0
;
CvBlobs
blobs
=
new
CvBlobs
();
Cv2
.
CvtColor
(
imageMat
,
imageMat
,
ColorConversionCodes
.
BGRA2BGR
);
Cv2
.
CvtColor
(
imageMat
,
grayMat
,
ColorConversionCodes
.
RGB2GRAY
);
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
if
(
i
==
0
)
{
sampThreshold
=
151
;
}
else
{
sampThreshold
=
161
;
}
Cv2
.
Threshold
(
grayMat
,
thresholdMat
,
sampThreshold
,
255
,
ThresholdTypes
.
BinaryInv
);
Cv2
.
MedianBlur
(
thresholdMat
,
thresholdMat
,
7
);
blobs
.
Label
(
thresholdMat
);
List
<
CvBlob
>
blobL
=
blobs
.
Values
.
Where
(
a
=>
a
.
Area
>
3
&&
a
.
Centroid
.
DistanceTo
(
radiusPtOut
.
pt
)
>
radiusPt
.
radius
&&
a
.
Centroid
.
DistanceTo
(
radiusPtOut
.
pt
)
<
radiusPtOut
.
radius
).
ToList
();
blobL
.
Sort
((
a
,
b
)
=>
a
.
Area
.
CompareTo
(
b
.
Area
));
if
(
blobL
.
Count
==
0
)
{
continue
;
}
minArea
=
blobL
[
0
].
Area
;
maxArea
=
blobL
[
blobL
.
Count
-
1
].
Area
;
if
(
i
==
0
)
{
blobNum
=
blobL
.
Count
();
proportion
=
maxArea
/
minArea
;
}
else
{
if
(
blobNum
>
blobL
.
Count
&&
proportion
<
maxArea
/
minArea
||
blobL
.
Count
<
100
)
{
minThreshold
=
151
;
}
else
{
minThreshold
=
161
;
}
}
}
Cv2
.
Threshold
(
grayMat
,
thresholdMat
,
minThreshold
,
255
,
ThresholdTypes
.
BinaryInv
);
blobs
.
Label
(
thresholdMat
);
CvBlob
selectBlob
=
null
;
foreach
(
CvBlob
item
in
blobs
.
Values
)
{
if
(
item
.
Rect
.
Contains
(
markX
,
markY
))
{
if
(
selectBlob
==
null
)
{
selectBlob
=
item
;
}
else
{
if
(
selectBlob
.
Area
>
item
.
Area
)
{
selectBlob
=
item
;
}
}
}
}
if
(
selectBlob
==
null
)
{
return
-
1
;
}
selectBlob
.
Contour
.
Render
(
imageMat
,
Scalar
.
Red
);
image
=
BitmapConverter
.
ToBitmap
(
imageMat
);
return
selectBlob
.
Area
;
}
/// <summary>
/// <summary>
/// 获取单个元器件的特征
/// 获取单个元器件的特征
...
@@ -1232,32 +1356,123 @@ namespace Acc.Img
...
@@ -1232,32 +1356,123 @@ namespace Acc.Img
public
static
int
GetFeature
(
ref
Image
image
,
int
markX
,
int
markY
)
public
static
int
GetFeature
(
ref
Image
image
,
int
markX
,
int
markY
)
{
{
Mat
imageMat
=
BitmapConverter
.
ToMat
(
new
Bitmap
(
image
));
Mat
imageMat
=
BitmapConverter
.
ToMat
(
new
Bitmap
(
image
));
Cv2
.
CvtColor
(
imageMat
,
imageMat
,
ColorConversionCodes
.
BGRA2BGR
);
Mat
dst
=
new
Mat
();
Mat
dst
=
new
Mat
();
Cv2
.
CvtColor
(
imageMat
,
dst
,
ColorConversionCodes
.
RGB2GRAY
);
//全局二值化
Cv2
.
Threshold
(
dst
,
dst
,
0
,
255
,
ThresholdTypes
.
Otsu
|
ThresholdTypes
.
BinaryInv
);
//Cv2.CvtColor(imageMat, gradMat, ColorConversionCodes.RGB2GRAY);
image
=
BitmapConverter
.
ToBitmap
(
dst
);
////全局二值化
CvBlobs
blobs
=
new
CvBlobs
();
//Cv2.Threshold(gradMat, dst, 0, 255, ThresholdTypes.Otsu |ThresholdTypes.BinaryInv);
blobs
.
Label
(
dst
);
int
blobArea
=
-
1
;
//image = BitmapConverter.ToBitmap(dst);
foreach
(
CvBlob
blob
in
blobs
.
Values
)
{
//CvBlobs blobs = new CvBlobs();
if
(
blob
.
Rect
.
Contains
(
new
OpenCvSharp
.
Point
(
markX
,
markY
)))
//blobs.Label(dst);
//int blobArea = -1;
//foreach (CvBlob blob in blobs.Values)
//{
// if (blob.Rect.Contains(new OpenCvSharp.Point(markX, markY)))
// {
// if (blob.Area < blobArea || blobArea == -1)
// {
// blobArea = blob.Area;
// }
// }
//}
Mat
[]
mats
=
new
Mat
[]
{
imageMat
};
//一张图片,初始化为panda
Mat
hist
=
new
Mat
();
//用来接收直方图
int
[]
channels
=
new
int
[]
{
0
};
//一个通道,初始化为通道0
int
[]
histsize
=
new
int
[]
{
256
};
//一个通道,初始化为256箱子
Rangef
[]
range
=
new
Rangef
[
1
];
//一个通道,值范围
range
[
0
].
Start
=
0.0F
;
//从0开始(含)
range
[
0
].
End
=
256.0F
;
//到256结束(不含)
Mat
mask
=
new
Mat
();
//不做掩码
Cv2
.
CalcHist
(
mats
,
channels
,
mask
,
hist
,
1
,
histsize
,
range
);
//计算灰度图,dim为1 1维
double
total
=
0
;
for
(
int
i
=
0
;
i
<
256
;
i
++)
//灰度值总数量
{
total
=
total
+
hist
.
Get
<
double
>(
i
);
}
double
percent
=
0
;
int
startIndex
=
-
1
;
int
endIndex
=
-
1
;
for
(
int
i
=
0
;
i
<
256
;
i
++)
//直方图
{
double
len
=
hist
.
Get
<
double
>(
i
);
if
(
len
>
100
)
{
//灰度值的像素数小于100的忽略
if
(
startIndex
==
-
1
)
{
startIndex
=
i
;
}
endIndex
=
i
-
1
;
percent
=
percent
+
len
/
total
;
//近似的认为元器件的灰度值 数量占总数的百分比小于10%
//if (percent > 0.1)
//{
// break;
//}
}
}
int
areaBlob
=
-
1
;
int
blobCount
=
0
;
Mat
grayMat
=
new
Mat
();
CvBlob
minBlob
=
null
;
Cv2
.
CvtColor
(
imageMat
,
grayMat
,
ColorConversionCodes
.
RGB2GRAY
);
for
(
int
i
=
endIndex
;
i
>
startIndex
;
i
--)
{
CvBlobs
blobs
=
new
CvBlobs
();
Cv2
.
Threshold
(
grayMat
,
dst
,
i
,
255
,
ThresholdTypes
.
BinaryInv
);
blobs
.
Label
(
dst
);
int
minArea
=
-
1
;
foreach
(
CvBlob
blob
in
blobs
.
Values
)
{
{
if
(
blob
.
Area
<
blobArea
||
blobArea
==
-
1
)
if
(
blob
.
Rect
.
Contains
(
new
OpenCvSharp
.
Point
(
markX
,
markY
))
)
{
{
blobArea
=
blob
.
Area
;
if
(
blob
.
Area
<
minArea
||
minArea
==
-
1
)
{
minArea
=
blob
.
Area
;
if
(
minBlob
==
null
)
{
minBlob
=
blob
;
}
}
}
}
}
}
List
<
CvBlob
>
blobList
=
blobs
.
Values
.
Where
(
b
=>
b
.
Area
>
minArea
).
ToList
<
CvBlob
>();
int
currentBlobCount
=
blobList
.
Count
;
if
(
currentBlobCount
<=
20
||
minArea
==
-
1
)
{
continue
;
}
if
(
minArea
*
2
<=
areaBlob
&&
areaBlob
!=
-
1
&&
blobCount
*
1.5
<
currentBlobCount
&&
blobCount
!=
-
1
)
{
Console
.
WriteLine
(
"thresh:"
+
i
+
" = "
+
minArea
+
" count = "
+
currentBlobCount
);
minBlob
.
Contour
.
Render
(
imageMat
,
Scalar
.
Red
);
//image = BitmapConverter.ToBitmap(imageMat);
image
=
BitmapConverter
.
ToBitmap
(
dst
);
return
minArea
;
}
areaBlob
=
minArea
;
blobCount
=
currentBlobCount
;
}
}
return
blobArea
;
Console
.
WriteLine
(
"End"
);
return
-
1
;
}
}
//获取圆心半径
//获取圆心半径
public
struct
R
e
diusPt
public
struct
R
a
diusPt
{
{
public
OpenCvSharp
.
Point
pt
;
public
OpenCvSharp
.
Point
pt
;
public
int
radius
;
public
int
radius
;
}
}
public
static
bool
GetCenter
(
Mat
srcMat
,
out
R
ediusPt
re
diusPt
)
public
static
bool
GetCenter
(
Mat
srcMat
,
out
R
adiusPt
ra
diusPt
)
{
{
Mat
grayMAT
=
srcMat
.
Clone
();
Mat
grayMAT
=
srcMat
.
Clone
();
Cv2
.
CvtColor
(
grayMAT
,
grayMAT
,
ColorConversionCodes
.
BGR2GRAY
);
Cv2
.
CvtColor
(
grayMAT
,
grayMAT
,
ColorConversionCodes
.
BGR2GRAY
);
...
@@ -1289,24 +1504,24 @@ namespace Acc.Img
...
@@ -1289,24 +1504,24 @@ namespace Acc.Img
if
(
centerMat
!=
null
)
if
(
centerMat
!=
null
)
{
{
pt
=
centerMat
.
CalcCentroid
();
pt
=
centerMat
.
CalcCentroid
();
r
e
diusPt
.
pt
.
X
=
centerMat
.
Rect
.
Width
/
2
+
centerMat
.
Rect
.
X
;
r
a
diusPt
.
pt
.
X
=
centerMat
.
Rect
.
Width
/
2
+
centerMat
.
Rect
.
X
;
r
e
diusPt
.
pt
.
Y
=
centerMat
.
Rect
.
Height
/
2
+
centerMat
.
Rect
.
Y
;
r
a
diusPt
.
pt
.
Y
=
centerMat
.
Rect
.
Height
/
2
+
centerMat
.
Rect
.
Y
;
if
(
centerMat
.
Rect
.
Width
<
centerMat
.
Rect
.
Height
)
if
(
centerMat
.
Rect
.
Width
<
centerMat
.
Rect
.
Height
)
r
e
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Width
*
0.5
);
r
a
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Width
*
0.5
);
else
else
r
e
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Height
*
0.5
);
r
a
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Height
*
0.5
);
return
true
;
return
true
;
}
}
else
else
{
{
r
e
diusPt
.
radius
=
-
1
;
r
a
diusPt
.
radius
=
-
1
;
r
e
diusPt
.
pt
=
new
OpenCvSharp
.
Point
(
0
,
0
);
r
a
diusPt
.
pt
=
new
OpenCvSharp
.
Point
(
0
,
0
);
return
false
;
return
false
;
}
}
}
}
//获取最外轮廓
//获取最外轮廓
public
static
bool
GetOutContour
(
Mat
srcMat
,
out
R
ediusPt
re
diusPt
)
public
static
bool
GetOutContour
(
Mat
srcMat
,
out
R
adiusPt
ra
diusPt
)
{
{
Mat
grayMAT
=
srcMat
.
Clone
();
Mat
grayMAT
=
srcMat
.
Clone
();
Cv2
.
CvtColor
(
grayMAT
,
grayMAT
,
ColorConversionCodes
.
BGR2GRAY
);
Cv2
.
CvtColor
(
grayMAT
,
grayMAT
,
ColorConversionCodes
.
BGR2GRAY
);
...
@@ -1339,18 +1554,18 @@ namespace Acc.Img
...
@@ -1339,18 +1554,18 @@ namespace Acc.Img
if
(
centerMat
!=
null
)
if
(
centerMat
!=
null
)
{
{
pt
=
centerMat
.
CalcCentroid
();
pt
=
centerMat
.
CalcCentroid
();
r
e
diusPt
.
pt
.
X
=
(
int
)
pt
.
X
;
r
a
diusPt
.
pt
.
X
=
(
int
)
pt
.
X
;
r
e
diusPt
.
pt
.
Y
=
(
int
)
pt
.
Y
;
r
a
diusPt
.
pt
.
Y
=
(
int
)
pt
.
Y
;
if
(
centerMat
.
Rect
.
Width
>
centerMat
.
Rect
.
Height
)
if
(
centerMat
.
Rect
.
Width
>
centerMat
.
Rect
.
Height
)
r
e
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Width
*
0.5
);
r
a
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Width
*
0.5
);
else
else
r
e
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Height
*
0.5
);
r
a
diusPt
.
radius
=
(
int
)
Math
.
Round
(
centerMat
.
Rect
.
Height
*
0.5
);
return
true
;
return
true
;
}
}
else
else
{
{
r
e
diusPt
.
radius
=
-
1
;
r
a
diusPt
.
radius
=
-
1
;
r
e
diusPt
.
pt
=
new
OpenCvSharp
.
Point
(
0
,
0
);
r
a
diusPt
.
pt
=
new
OpenCvSharp
.
Point
(
0
,
0
);
return
false
;
return
false
;
}
}
}
}
...
...
AccImage/SplitItem.cs
查看文件 @
54f0855
...
@@ -106,7 +106,7 @@ namespace AccImage
...
@@ -106,7 +106,7 @@ namespace AccImage
if
(
Math
.
Abs
(
c
.
distanceToCenter
-
labelCircle
.
distanceToCenter
)
<
h
)
if
(
Math
.
Abs
(
c
.
distanceToCenter
-
labelCircle
.
distanceToCenter
)
<
h
)
{
{
//两圆心之间的距离+直径小于W认为是同一个元器件
//两圆心之间的距离+直径小于W认为是同一个元器件
if
(
c
.
distanceToCircle
(
labelCircle
)
<
w
)
if
(
c
.
distanceToCircle
(
labelCircle
)
<
w
+
h
*
2
/
3
)
{
{
groupCircle
.
Add
(
c
);
groupCircle
.
Add
(
c
);
allreadyGroup
.
Add
(
i
);
allreadyGroup
.
Add
(
i
);
...
@@ -115,7 +115,7 @@ namespace AccImage
...
@@ -115,7 +115,7 @@ namespace AccImage
}
}
}
}
}
}
allGroupCircle
.
Add
(
groupCircle
);
allGroupCircle
.
Add
(
groupCircle
);
if
(
allreadyGroup
.
Count
==
circles
.
Count
)
if
(
allreadyGroup
.
Count
==
circles
.
Count
)
{
{
break
;
break
;
...
...
Demo/MainForm.cs
查看文件 @
54f0855
...
@@ -93,8 +93,8 @@ namespace Acc.Demo
...
@@ -93,8 +93,8 @@ namespace Acc.Demo
imageBox
.
Image
=
orginalImage
;
imageBox
.
Image
=
orginalImage
;
}
}
private
int
markX
=
-
1
;
private
static
int
markX
=
-
1
;
private
int
markY
=
-
1
;
private
static
int
markY
=
-
1
;
private
void
imageBox_MouseDown
(
object
sender
,
MouseEventArgs
e
)
private
void
imageBox_MouseDown
(
object
sender
,
MouseEventArgs
e
)
{
{
...
@@ -148,7 +148,8 @@ namespace Acc.Demo
...
@@ -148,7 +148,8 @@ namespace Acc.Demo
{
{
ClearStatusBar
();
ClearStatusBar
();
Image
image
=
orginalImage
;
Image
image
=
orginalImage
;
int
feature
=
ImageUtil
.
GetFeature
(
ref
image
,
markX
,
markY
);
//int feature = ImageUtil.GetFeature(ref image, markX, markY);
int
feature
=
ImageUtil
.
GetGrayValue
(
ref
image
,
markX
,
markY
);
textBoxFeature
.
Text
=
feature
.
ToString
();
textBoxFeature
.
Text
=
feature
.
ToString
();
imageBox
.
Image
=
image
;
imageBox
.
Image
=
image
;
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论