diff --git a/app/app.py b/app/app.py index 1dd2703..e01361e 100644 --- a/app/app.py +++ b/app/app.py @@ -11,7 +11,7 @@ @app.route('/') def detect_colour(): # Load the image, convert to grayscale - img = cv2.imread(image_path) + img = cv2.imread('/Users/uzimamalik/Desktop/green.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Apply Otsu's thresholding to get a binary image @@ -28,7 +28,15 @@ def detect_colour(): mask = cv2.drawContours(np.zeros_like(binary), [largest_contour], 0, (255, 255, 255), -1) # Compute the average colour of the piece of clothing - average_colour = cv2.mean(img, mask=mask) + average_colour = cv2.mean(img, mask=mask)[:3] + + average_colour = average_colour[::-1] + + average_colour_dict = { + "red": average_colour[0], + "green": average_colour[1], + "blue": average_colour[2] + } return jsonify(average_colour) diff --git a/app/assets/images/hanger.png b/app/assets/images/hanger.png new file mode 100644 index 0000000..e8baa6e Binary files /dev/null and b/app/assets/images/hanger.png differ diff --git a/app/lib/camera.dart b/app/lib/camera.dart index d1fe140..1787783 100644 --- a/app/lib/camera.dart +++ b/app/lib/camera.dart @@ -2,8 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; -import 'package:image/image.dart' as img; -import 'package:http/http.dart' as http; +import 'load.dart'; import 'request.dart'; // allows the user to take pictures @@ -125,10 +124,13 @@ class DisplayPictureScreen extends StatelessWidget { }, child: const Text("Retake")), TextButton( - onPressed: () { + onPressed: () async { + var message = await Navigator.push(context, + MaterialPageRoute(builder: (context) { + return const Load(); + })); _processImage(); runPythonScript(imagePath); - //Navigator.pop(context); }, child: const Text("Done")), ]) @@ -146,5 +148,8 @@ void runPythonScript(String imagePath) async { void _processImage() async { var data = await getData("http://10.0.2.2:5000/"); var decodedData = jsonDecode(data); - print(decodedData); + var bgrValues = data['average_colour']; + var rgbValues = bgrValues.sublist(0, 3).reversed.toList(); + var hexValue = '#${rgbValues.map((c) => c.toRadixString(16).padLeft(2, '0')).join()}'; + debugPrint(hexValue); } diff --git a/app/lib/empty.dart b/app/lib/empty.dart new file mode 100644 index 0000000..02e74d0 --- /dev/null +++ b/app/lib/empty.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Invoke "debug painting" (press "p" in the console, choose the + // "Toggle Debug Paint" action from the Flutter Inspector in Android + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) + // to see the wireframe for each widget. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headlineMedium, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} \ No newline at end of file diff --git a/app/lib/load.dart b/app/lib/load.dart new file mode 100644 index 0000000..4e383f8 --- /dev/null +++ b/app/lib/load.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'result.dart'; +import 'package:loading_animation_widget/loading_animation_widget.dart'; + +class Load extends StatefulWidget { + const Load({ + super.key, + }); + + @override + State createState() => _LoadState(); +} + +class _LoadState extends State { + @override + void initState() { + super.initState(); + _navigateToHome(); + } + + _navigateToHome() async { + await Future.delayed(const Duration(milliseconds: 2500), () {}); + if (!context.mounted) return; + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => const ResultPage(detected: 0xFFD65DB1,))); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/hanger.png', + width: 275, + height: 275, + ), + SizedBox(height: 20), + LoadingAnimationWidget.staggeredDotsWave( + color: Colors.pink, + size: 200, + ), + ], + ), + ), + ); + } +} diff --git a/app/lib/main.dart b/app/lib/main.dart index fd29ac3..5fe9bd5 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -1,10 +1,8 @@ import 'dart:async'; -import 'dart:io'; +import 'package:app/splash.dart'; import 'package:flutter/material.dart'; import 'package:camera/camera.dart'; -import 'package:app/splash.dart'; - -import 'camera.dart'; +// import 'package:app/splash.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -13,5 +11,6 @@ void main() async { runApp(MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData.light(), - home: Splash(camera: cameraUsed))); + home: Splash(camera: cameraUsed,))); + } diff --git a/app/lib/result.dart b/app/lib/result.dart new file mode 100644 index 0000000..2231271 --- /dev/null +++ b/app/lib/result.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:tinycolor2/tinycolor2.dart'; + +class ResultPage extends StatelessWidget { + const ResultPage({ + super.key, + required this.detected + }); + final int detected; + + @override + Widget build(BuildContext context) { + Color detectedColor = Color(detected); + TinyColor tinyColor = TinyColor.fromColor(detectedColor); + + TinyColor color1 = tinyColor.spin(60); + color1 = color1.brighten(50); + + TinyColor color2 = tinyColor.spin(300); + color2 = color2.darken(50); + + return Stack( + children: [ + const Positioned(top:50, left:50, child: Text('Detected colour:', style: TextStyle(fontSize: 20))), + Positioned(top:100, left:50, child: Container( + width: 100, + height: 50, + color: detectedColor, + )), + const Positioned(top:200, left:50, child:Text('Colours that would match:', style: TextStyle(fontSize: 20),)), + Positioned(top:250, left:50, child:Row(children: [Container( + width: 100, + height: 50, + color: color1.color, + ), Container( + width: 100, + height: 50, + color: color2.color, + )])), + Positioned(bottom: 50, right: 50, + child: TextButton( + onPressed: () { + Navigator.of(context).popUntil((route) => route.isFirst); + }, + child: const Text("Done"), + )) + ]); + } + +} diff --git a/app/lib/splash.dart b/app/lib/splash.dart index e30979f..7257392 100644 --- a/app/lib/splash.dart +++ b/app/lib/splash.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'camera.dart'; diff --git a/app/pubspec.lock b/app/pubspec.lock index d2e04c1..3e2cc28 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -224,6 +224,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + loading_animation_widget: + dependency: "direct main" + description: + name: loading_animation_widget + sha256: "1901682600273a966c34cf44a85fc5355da92a8d08a8a43c11adc4e471993e3a" + url: "https://pub.dev" + source: hosted + version: "1.2.0+4" matcher: dependency: transitive description: @@ -328,6 +336,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.0" + pigment: + dependency: transitive + description: + name: pigment + sha256: b8c56059e21ecb9379a304c78a4f20e399d41e54384a7f64de21103b4b5c38dd + url: "https://pub.dev" + source: hosted + version: "1.0.4" platform: dependency: transitive description: @@ -461,6 +477,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.16" + tinycolor2: + dependency: "direct main" + description: + name: tinycolor2 + sha256: "81850c32ac8d4dcff37299bf3e52bcad4f4db6bc73d4b06727c9922de3766390" + url: "https://pub.dev" + source: hosted + version: "3.0.1" typed_data: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index a50ad44..4abcb6a 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -30,10 +30,11 @@ environment: dependencies: flutter: sdk: flutter + loading_animation_widget: image: ^4.0.16 opencv_4: ^1.0.0 http: ^0.13.5 - + tinycolor2: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2