Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
22_23-J 50
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
22_23-J 50
22_23-J 50
Commits
45b386e5
Commit
45b386e5
authored
May 12, 2023
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Result view functions added
parent
60cb60e4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
295 additions
and
0 deletions
+295
-0
Frontend/currency detector/PrePostProcessor.java
Frontend/currency detector/PrePostProcessor.java
+143
-0
Frontend/currency detector/ResultView.java
Frontend/currency detector/ResultView.java
+74
-0
Frontend/currency detector/ResultView2.java
Frontend/currency detector/ResultView2.java
+78
-0
No files found.
Frontend/currency detector/PrePostProcessor.java
0 → 100644
View file @
45b386e5
package
com.sliit.lkrdetectionandroid
;
import
android.graphics.Rect
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Comparator
;
class
Result
{
int
classIndex
;
Float
score
;
Rect
rect
;
public
Result
(
int
cls
,
Float
output
,
Rect
rect
)
{
this
.
classIndex
=
cls
;
this
.
score
=
output
;
this
.
rect
=
rect
;
}
};
public
class
PrePostProcessor
{
// for yolov5 model, no need to apply MEAN and STD
static
float
[]
NO_MEAN_RGB
=
new
float
[]
{
0.0f
,
0.0f
,
0.0f
};
static
float
[]
NO_STD_RGB
=
new
float
[]
{
1.0f
,
1.0f
,
1.0f
};
// model input image size
static
int
mInputWidth
=
640
;
static
int
mInputHeight
=
640
;
// model output is of size 25200*(num_of_class+5)
private
static
int
mOutputRow
=
25200
;
// as decided by the YOLOv5 model for input image of size 640*640
private
static
int
mOutputColumn
=
11
;
// left, top, right, bottom, score and 80 class probability
private
static
float
mThreshold
=
0.50f
;
// score above which a detection is generated
private
static
int
mNmsLimit
=
15
;
static
String
[]
mClasses
;
// The two methods nonMaxSuppression and IOU below are ported from https://github.com/hollance/YOLO-CoreML-MPSNNGraph/blob/master/Common/Helpers.swift
/**
Removes bounding boxes that overlap too much with other boxes that have
a higher score.
- Parameters:
- boxes: an array of bounding boxes and their scores
- limit: the maximum number of boxes that will be selected
- threshold: used to decide whether boxes overlap too much
*/
static
ArrayList
<
Result
>
nonMaxSuppression
(
ArrayList
<
Result
>
boxes
,
int
limit
,
float
threshold
)
{
// Do an argsort on the confidence scores, from high to low.
Collections
.
sort
(
boxes
,
new
Comparator
<
Result
>()
{
@Override
public
int
compare
(
Result
o1
,
Result
o2
)
{
return
o1
.
score
.
compareTo
(
o2
.
score
);
}
});
ArrayList
<
Result
>
selected
=
new
ArrayList
<>();
boolean
[]
active
=
new
boolean
[
boxes
.
size
()];
Arrays
.
fill
(
active
,
true
);
int
numActive
=
active
.
length
;
// The algorithm is simple: Start with the box that has the highest score.
// Remove any remaining boxes that overlap it more than the given threshold
// amount. If there are any boxes left (i.e. these did not overlap with any
// previous boxes), then repeat this procedure, until no more boxes remain
// or the limit has been reached.
boolean
done
=
false
;
for
(
int
i
=
0
;
i
<
boxes
.
size
()
&&
!
done
;
i
++)
{
if
(
active
[
i
])
{
Result
boxA
=
boxes
.
get
(
i
);
selected
.
add
(
boxA
);
if
(
selected
.
size
()
>=
limit
)
break
;
for
(
int
j
=
i
+
1
;
j
<
boxes
.
size
();
j
++)
{
if
(
active
[
j
])
{
Result
boxB
=
boxes
.
get
(
j
);
if
(
IOU
(
boxA
.
rect
,
boxB
.
rect
)
>
threshold
)
{
active
[
j
]
=
false
;
numActive
-=
1
;
if
(
numActive
<=
0
)
{
done
=
true
;
break
;
}
}
}
}
}
}
return
selected
;
}
/**
Computes intersection-over-union overlap between two bounding boxes.
*/
static
float
IOU
(
Rect
a
,
Rect
b
)
{
float
areaA
=
(
a
.
right
-
a
.
left
)
*
(
a
.
bottom
-
a
.
top
);
if
(
areaA
<=
0.0
)
return
0.0f
;
float
areaB
=
(
b
.
right
-
b
.
left
)
*
(
b
.
bottom
-
b
.
top
);
if
(
areaB
<=
0.0
)
return
0.0f
;
float
intersectionMinX
=
Math
.
max
(
a
.
left
,
b
.
left
);
float
intersectionMinY
=
Math
.
max
(
a
.
top
,
b
.
top
);
float
intersectionMaxX
=
Math
.
min
(
a
.
right
,
b
.
right
);
float
intersectionMaxY
=
Math
.
min
(
a
.
bottom
,
b
.
bottom
);
float
intersectionArea
=
Math
.
max
(
intersectionMaxY
-
intersectionMinY
,
0
)
*
Math
.
max
(
intersectionMaxX
-
intersectionMinX
,
0
);
return
intersectionArea
/
(
areaA
+
areaB
-
intersectionArea
);
}
static
ArrayList
<
Result
>
outputsToNMSPredictions
(
float
[]
outputs
,
float
imgScaleX
,
float
imgScaleY
,
float
ivScaleX
,
float
ivScaleY
,
float
startX
,
float
startY
)
{
ArrayList
<
Result
>
results
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
mOutputRow
;
i
++)
{
if
(
outputs
[
i
*
mOutputColumn
+
4
]
>
mThreshold
)
{
float
x
=
outputs
[
i
*
mOutputColumn
];
float
y
=
outputs
[
i
*
mOutputColumn
+
1
];
float
w
=
outputs
[
i
*
mOutputColumn
+
2
];
float
h
=
outputs
[
i
*
mOutputColumn
+
3
];
float
left
=
imgScaleX
*
(
x
-
w
/
2
);
float
top
=
imgScaleY
*
(
y
-
h
/
2
);
float
right
=
imgScaleX
*
(
x
+
w
/
2
);
float
bottom
=
imgScaleY
*
(
y
+
h
/
2
);
float
max
=
outputs
[
i
*
mOutputColumn
+
5
];
int
cls
=
0
;
for
(
int
j
=
0
;
j
<
mOutputColumn
-
5
;
j
++)
{
if
(
outputs
[
i
*
mOutputColumn
+
5
+
j
]
>
max
)
{
max
=
outputs
[
i
*
mOutputColumn
+
5
+
j
];
cls
=
j
;
}
}
Rect
rect
=
new
Rect
((
int
)(
startX
+
ivScaleX
*
left
),
(
int
)(
startY
+
top
*
ivScaleY
),
(
int
)(
startX
+
ivScaleX
*
right
),
(
int
)(
startY
+
ivScaleY
*
bottom
));
Result
result
=
new
Result
(
cls
,
outputs
[
i
*
mOutputColumn
+
4
],
rect
);
results
.
add
(
result
);
}
}
return
nonMaxSuppression
(
results
,
mNmsLimit
,
mThreshold
);
}
}
Frontend/currency detector/ResultView.java
0 → 100644
View file @
45b386e5
package
com.sliit.lkrdetectionandroid
;
import
static
androidx
.
constraintlayout
.
helper
.
widget
.
MotionEffect
.
TAG
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.RectF
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.view.View
;
import
java.util.ArrayList
;
public
class
ResultView
extends
View
{
private
final
static
int
TEXT_X
=
40
;
private
final
static
int
TEXT_Y
=
35
;
private
final
static
int
TEXT_WIDTH
=
260
;
private
final
static
int
TEXT_HEIGHT
=
50
;
private
Paint
mPaintRectangle
;
private
Paint
mPaintText
;
private
ArrayList
<
Result
>
mResults
;
public
ResultView
(
Context
context
)
{
super
(
context
);
}
public
ResultView
(
Context
context
,
AttributeSet
attrs
){
super
(
context
,
attrs
);
mPaintRectangle
=
new
Paint
();
mPaintRectangle
.
setColor
(
Color
.
YELLOW
);
mPaintText
=
new
Paint
();
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
if
(
mResults
==
null
||
mResults
.
size
()
==
0
){
String
msg
=
"Detection faild! Please tap the Check again button to try again"
;
NoteDetector
.
textView_result
.
setText
(
msg
);
return
;
}
for
(
Result
result
:
mResults
)
{
mPaintRectangle
.
setStrokeWidth
(
5
);
mPaintRectangle
.
setStyle
(
Paint
.
Style
.
STROKE
);
canvas
.
drawRect
(
result
.
rect
,
mPaintRectangle
);
Path
mPath
=
new
Path
();
RectF
mRectF
=
new
RectF
(
result
.
rect
.
left
,
result
.
rect
.
top
,
result
.
rect
.
left
+
TEXT_WIDTH
,
result
.
rect
.
top
+
TEXT_HEIGHT
);
mPath
.
addRect
(
mRectF
,
Path
.
Direction
.
CW
);
mPaintText
.
setColor
(
Color
.
MAGENTA
);
canvas
.
drawPath
(
mPath
,
mPaintText
);
mPaintText
.
setColor
(
Color
.
WHITE
);
mPaintText
.
setStrokeWidth
(
0
);
mPaintText
.
setStyle
(
Paint
.
Style
.
FILL
);
mPaintText
.
setTextSize
(
32
);
canvas
.
drawText
(
String
.
format
(
"%s %.2f"
,
PrePostProcessor
.
mClasses
[
result
.
classIndex
],
result
.
score
),
result
.
rect
.
left
+
TEXT_X
,
result
.
rect
.
top
+
TEXT_Y
,
mPaintText
);
NoteDetector
.
textView_result
.
setText
(
"LKR "
+
String
.
format
(
PrePostProcessor
.
mClasses
[
result
.
classIndex
]+
" Note Detected"
));
}
}
public
void
setResults
(
ArrayList
<
Result
>
results
)
{
mResults
=
results
;
}
}
Frontend/currency detector/ResultView2.java
0 → 100644
View file @
45b386e5
package
com.sliit.lkrdetectionandroid
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.RectF
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
java.util.ArrayList
;
public
class
ResultView2
extends
View
{
private
final
static
int
TEXT_X
=
40
;
private
final
static
int
TEXT_Y
=
35
;
private
final
static
int
TEXT_WIDTH
=
260
;
private
final
static
int
TEXT_HEIGHT
=
50
;
private
Paint
mPaintRectangle
;
private
Paint
mPaintText
;
private
ArrayList
<
Result
>
mResults
;
public
ResultView2
(
Context
context
)
{
super
(
context
);
}
public
ResultView2
(
Context
context
,
AttributeSet
attrs
){
super
(
context
,
attrs
);
mPaintRectangle
=
new
Paint
();
mPaintRectangle
.
setColor
(
Color
.
YELLOW
);
mPaintText
=
new
Paint
();
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
if
(
mResults
==
null
||
mResults
.
size
()
==
0
){
String
msg
=
"Detection faild! Please tap the 'Add a note' button to try again"
;
NoteCounter
.
textView_result
.
setText
(
msg
);
return
;
}
for
(
Result
result
:
mResults
)
{
mPaintRectangle
.
setStrokeWidth
(
5
);
mPaintRectangle
.
setStyle
(
Paint
.
Style
.
STROKE
);
canvas
.
drawRect
(
result
.
rect
,
mPaintRectangle
);
Path
mPath
=
new
Path
();
RectF
mRectF
=
new
RectF
(
result
.
rect
.
left
,
result
.
rect
.
top
,
result
.
rect
.
left
+
TEXT_WIDTH
,
result
.
rect
.
top
+
TEXT_HEIGHT
);
mPath
.
addRect
(
mRectF
,
Path
.
Direction
.
CW
);
mPaintText
.
setColor
(
Color
.
MAGENTA
);
canvas
.
drawPath
(
mPath
,
mPaintText
);
mPaintText
.
setColor
(
Color
.
WHITE
);
mPaintText
.
setStrokeWidth
(
0
);
mPaintText
.
setStyle
(
Paint
.
Style
.
FILL
);
mPaintText
.
setTextSize
(
32
);
canvas
.
drawText
(
String
.
format
(
"%s %.2f"
,
PrePostProcessor
.
mClasses
[
result
.
classIndex
],
result
.
score
),
result
.
rect
.
left
+
TEXT_X
,
result
.
rect
.
top
+
TEXT_Y
,
mPaintText
);
String
a
=
String
.
format
(
PrePostProcessor
.
mClasses
[
result
.
classIndex
]);
int
b
=
Integer
.
parseInt
(
a
);
NoteCounter
.
counts
.
add
(
b
);
NoteCounter
.
textView_result
.
setText
(
"LKR "
+
String
.
format
(
PrePostProcessor
.
mClasses
[
result
.
classIndex
]+
" Note Detected."
));
}
}
public
void
setResults
(
ArrayList
<
Result
>
results
)
{
mResults
=
results
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment