Skip to content

Commit

Permalink
houghLines, warpPerspectiveTransform
Browse files Browse the repository at this point in the history
houghLines, warpPerspectiveTransform added
  • Loading branch information
AdityaMulgundkar committed Jul 18, 2020
1 parent 6ceaeae commit e45b878
Show file tree
Hide file tree
Showing 11 changed files with 591 additions and 267 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ build/
.idea/workspace.xml
.idea/workspace.xml
.idea/workspace.xml
example/android/.settings/org.eclipse.buildship.core.prefs
example/android/app/.classpath
example/android/app/.project
example/android/app/.settings/org.eclipse.buildship.core.prefs
example/android/.project
android/.settings/org.eclipse.buildship.core.prefs
android/.project
android/.classpath
.idea/workspace.xml
.idea/libraries/Flutter_Plugins.xml
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ Since you're never going to just implement one function, there's a need to be ab
### Why not do a full binding?
I am actually planning to write a full binding and publish it separately later on. I understand that this implementation is lackluster & a lot of functions still need to be added. If you really need something, make a feature request.

### Why not use dart:ffi?
I've read up a few bad things about performance benchmarking in ffi, [refer] (https://news.ycombinator.com/item?id=17219291). Due to lack of a better option & the simplicity of method channels, I chose not to go with dart:ffi. Maybe, in the future, someone would build the project on dart:ffi instead of Java/Swift bindings & make it work exactly like OpenCV does. If I ever get the time or resources, I'll start another project in the name of "opencv_advanced".

### Why not use the core OpenCV classes like Mat?
Because I wanted to provide a simple interface - one that does not require the user to learn OpenCV or it's API. Instead, much of the way the library works is designed around Flutter/Dart, making it easier for Flutter users to pick it up.

Expand Down
106 changes: 79 additions & 27 deletions android/src/main/java/com/mulgundkar/opencv/OpenCV4Plugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public class OpenCV4Plugin implements FlutterPlugin, MethodCallHandler {

@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "opencv");
final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
"opencv");
channel.setMethodCallHandler(new OpenCV4Plugin());
}

Expand Down Expand Up @@ -62,81 +63,132 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
result.success(core.cvtColor((byte[]) call.argument("byteData"), (int) call.argument("outputType")));
break;
case "blur":
result.success(core.blur((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"), (ArrayList) call.argument("anchorPoint"), (int) call.argument("borderType")));
result.success(core.blur((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"),
(ArrayList) call.argument("anchorPoint"), (int) call.argument("borderType")));
break;
case "gaussianBlur":
result.success(core.gaussianBlur((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"), (double) call.argument("sigmaX")));
result.success(core.gaussianBlur((byte[]) call.argument("byteData"),
(ArrayList) call.argument("kernelSize"), (double) call.argument("sigmaX")));
break;
case "medianBlur":
result.success(core.medianBlur((byte[]) call.argument("byteData"), (int) call.argument("kernelSize")));
break;
case "bilateralFilter":
result.success(core.bilateralFilter((byte[]) call.argument("byteData"), (int) call.argument("diameter"), (int) call.argument("sigmaColor"), (int) call.argument("sigmaSpace"), (int) call.argument("borderType")));
result.success(core.bilateralFilter((byte[]) call.argument("byteData"), (int) call.argument("diameter"),
(int) call.argument("sigmaColor"), (int) call.argument("sigmaSpace"),
(int) call.argument("borderType")));
break;
case "boxFilter":
result.success(core.boxFilter((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"), (ArrayList) call.argument("kernelSize"), (ArrayList) call.argument("anchorPoint"), (boolean) call.argument("normalize"), (int) call.argument("borderType")));
result.success(core.boxFilter((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"),
(ArrayList) call.argument("kernelSize"), (ArrayList) call.argument("anchorPoint"),
(boolean) call.argument("normalize"), (int) call.argument("borderType")));
break;
case "sqrBoxFilter":
result.success(core.sqrBoxFilter((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"), (ArrayList) call.argument("kernelSize")));
result.success(core.sqrBoxFilter((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"),
(ArrayList) call.argument("kernelSize")));
break;
case "filter2D":
result.success(core.filter2D((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"), (ArrayList) call.argument("kernelSize")));
result.success(core.filter2D((byte[]) call.argument("byteData"), (int) call.argument("outputDepth"),
(ArrayList) call.argument("kernelSize")));
break;
case "dilate":
result.success(core.dilate((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize")));
result.success(
core.dilate((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize")));
break;
case "erode":
result.success(core.erode((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize")));
break;
case "morphologyEx":
result.success(core.morphologyEx((byte[]) call.argument("byteData"), (int) call.argument("operation"), (ArrayList) call.argument("kernelSize")));
result.success(core.morphologyEx((byte[]) call.argument("byteData"), (int) call.argument("operation"),
(ArrayList) call.argument("kernelSize")));
break;
case "pyrUp":
result.success(core.pyrUp((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"), (int) call.argument("borderType")));
result.success(core.pyrUp((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"),
(int) call.argument("borderType")));
break;
case "pyrDown":
result.success(core.pyrDown((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"), (int) call.argument("borderType")));
result.success(core.pyrDown((byte[]) call.argument("byteData"), (ArrayList) call.argument("kernelSize"),
(int) call.argument("borderType")));
break;
case "pyrMeanShiftFiltering":
result.success(core.pyrMeanShiftFiltering((byte[]) call.argument("byteData"), (double) call.argument("spatialWindowRadius"), (double) call.argument("colorWindowRadius")));
result.success(core.pyrMeanShiftFiltering((byte[]) call.argument("byteData"),
(double) call.argument("spatialWindowRadius"), (double) call.argument("colorWindowRadius")));
break;
case "threshold":
result.success(core.threshold((byte[]) call.argument("byteData"), (double) call.argument("thresholdValue"), (double) call.argument("maxThresholdValue"), (int) call.argument("thresholdType")));
result.success(
core.threshold((byte[]) call.argument("byteData"), (double) call.argument("thresholdValue"),
(double) call.argument("maxThresholdValue"), (int) call.argument("thresholdType")));
break;
case "adaptiveThreshold":
result.success(core.adaptiveThreshold((byte[]) call.argument("byteData"), (double) call.argument("maxValue"), (int) call.argument("adaptiveMethod"), (int) call.argument("thresholdType"), (int) call.argument("blockSize"), (double) call.argument("constantValue")));
result.success(
core.adaptiveThreshold((byte[]) call.argument("byteData"), (double) call.argument("maxValue"),
(int) call.argument("adaptiveMethod"), (int) call.argument("thresholdType"),
(int) call.argument("blockSize"), (double) call.argument("constantValue")));
break;
case "copyMakeBorder":
result.success(core.copyMakeBorder((byte[]) call.argument("byteData"), (int) call.argument("top"), (int) call.argument("bottom"), (int) call.argument("left"), (int) call.argument("right"), (int) call.argument("borderType")));
result.success(core.copyMakeBorder((byte[]) call.argument("byteData"), (int) call.argument("top"),
(int) call.argument("bottom"), (int) call.argument("left"), (int) call.argument("right"),
(int) call.argument("borderType")));
break;
case "sobel":
result.success(core.sobel((byte[]) call.argument("byteData"), (int) call.argument("depth"), (int) call.argument("dx"), (int) call.argument("dy")));
result.success(core.sobel((byte[]) call.argument("byteData"), (int) call.argument("depth"),
(int) call.argument("dx"), (int) call.argument("dy")));
break;
case "scharr":
result.success(core.scharr((byte[]) call.argument("byteData"), (int) call.argument("depth"), (int) call.argument("dx"), (int) call.argument("dy")));
result.success(core.scharr((byte[]) call.argument("byteData"), (int) call.argument("depth"),
(int) call.argument("dx"), (int) call.argument("dy")));
break;
case "laplacian":
result.success(core.laplacian((byte[]) call.argument("byteData"), (int) call.argument("depth")));
break;
case "distanceTransform":
result.success(core.distanceTransform((byte[]) call.argument("byteData"), (int) call.argument("distanceType"), (int) call.argument("maskSize")));
break;
/*
case "warpAffine":
result.success(core.warpAffine((byte[]) call.argument("byteData"), (int) call.argument("tranformMatrix"), (int) call.argument("size")));
break;
*/
result.success(core.distanceTransform((byte[]) call.argument("byteData"),
(int) call.argument("distanceType"), (int) call.argument("maskSize")));
break;
/*
* case "warpAffine": result.success(core.warpAffine((byte[])
* call.argument("byteData"), (int) call.argument("tranformMatrix"), (int)
* call.argument("size"))); break;
*/
case "resize":
result.success(core.resize((byte[]) call.argument("byteData"), (ArrayList) call.argument("outputSize"), (double) call.argument("fx"), (double) call.argument("fy"), (int) call.argument("interpolation")));
result.success(core.resize((byte[]) call.argument("byteData"), (ArrayList) call.argument("outputSize"),
(double) call.argument("fx"), (double) call.argument("fy"),
(int) call.argument("interpolation")));
break;
case "applyColorMap":
result.success(core.applyColorMap((byte[]) call.argument("byteData"), (int) call.argument("colorMap")));
break;
case "canny":
result.success(core.canny((byte[]) call.argument("byteData"), (double) call.argument("threshold1"), (double) call.argument("threshold2")));
result.success(core.canny((byte[]) call.argument("byteData"), (double) call.argument("threshold1"),
(double) call.argument("threshold2")));
break;
case "houghLines":
result.success(core.houghLines((byte[]) call.argument("byteData"), (double) call.argument("rho"),
(double) call.argument("theta"), (int) call.argument("threshold"),
(double) call.argument("srn"), (double) call.argument("stn"),
(double) call.argument("minTheta"), (double) call.argument("maxTheta"),
(String) call.argument("lineColor"), (int) call.argument("lineThickness"),
(int) call.argument("lineType"), (int) call.argument("shift")));
break;
case "houghLinesProbabilistic":
result.success(
core.houghLinesProbabilistic((byte[]) call.argument("byteData"), (double) call.argument("rho"),
(double) call.argument("theta"), (int) call.argument("threshold"),
(double) call.argument("minLineLength"), (double) call.argument("maxLineGap"),
(String) call.argument("lineColor"), (int) call.argument("lineThickness"),
(int) call.argument("lineType"), (int) call.argument("shift")));
break;
case "houghCircles":
result.success(core.houghCircles((byte[]) call.argument("byteData"), (int) call.argument("method"), (double) call.argument("dp"), (double) call.argument("minDist"), (double) call.argument("param1"), (double) call.argument("param2"), (int) call.argument("minRadius"), (int) call.argument("maxRadius"), (int) call.argument("centerWidth"), (String) call.argument("centerColor"), (int) call.argument("circleWidth"), (String) call.argument("circleColor")));
result.success(core.houghCircles((byte[]) call.argument("byteData"), (int) call.argument("method"),
(double) call.argument("dp"), (double) call.argument("minDist"),
(double) call.argument("param1"), (double) call.argument("param2"),
(int) call.argument("minRadius"), (int) call.argument("maxRadius"),
(int) call.argument("centerWidth"), (String) call.argument("centerColor"),
(int) call.argument("circleWidth"), (String) call.argument("circleColor")));
break;
case "warpPerspectiveTransform":
result.success(core.warpPerspectiveTransform((byte[]) call.argument("byteData"),
(ArrayList) call.argument("sourcePoints"), (ArrayList) call.argument("destinationPoints"), (ArrayList) call.argument("outputSize") ));
break;
default:
result.notImplemented();
Expand Down
Loading

0 comments on commit e45b878

Please sign in to comment.