Skip to content

Issue while trying to stitch photos on Android device in flutter app #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
GoxeeVladan opened this issue Jul 25, 2024 · 8 comments
Closed
Labels
question Further information is requested

Comments

@GoxeeVladan
Copy link

Read README carefully first
Star ⭐ this project if you want to ask a question, no star, no answer

Question

So i have a question on how to workaround this error i get when i try to stitch images: E/linker (15518): library "/system/vendor/lib/libOpenCL.so" ("/vendor/lib/libOpenCL.so") needed or dlopened by "/data/app/~~67wySL_d8_JZcyMgMvVaWw==/{app bundle id}skSn_oIwPiKc5JBH85EMGw==/base.apk!/lib/arm64-v8a/libopencv_dart.so" is not accessible for the namespace: [name="clns-4", ld_library_paths="", default_library_paths="/data/app/~~67wySL_d8_JZcyMgMvVaWw==/{app bundle id}?
Is it something known or is it me that does something wrong?

@GoxeeVladan GoxeeVladan added the question Further information is requested label Jul 25, 2024
@rainyl
Copy link
Owner

rainyl commented Jul 28, 2024

Could you please provide a reproducible example?

@GoxeeVladan
Copy link
Author

Here is the code where i'm using it:

import 'dart:io';

import 'package:camera/camera.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:get/get.dart';
import 'package:intel_booth_app/photos/car_images_list_view_model.dart';
import 'package:opencv_dart/opencv_dart.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

class Camera360Controller extends GetxController {
var progressPercentage = 0.obs;
var cameras = [].obs;
final carImagesListViewModel = Get.find();
final RxList imagePaths = [].obs;
var cameraController = Rx<CameraController?>(null);
var isCapturing = false.obs;

@OverRide
void onInit() {
super.onInit();
initializeCamera();
}

Future initializeCamera() async {
cameras.value = await availableCameras();
if (cameras.isNotEmpty) {
cameraController(CameraController(cameras.first, ResolutionPreset.high));
await cameraController.value?.initialize();
cameraController.refresh();
update();
}
}

Future startCapturing() async {
isCapturing.value = true;
progressPercentage.value = 0;
await captureAndStitchImages();
// Logic to capture and stitch images using opencv_dart will be implemented here
}

void updateProgress(int value) {
progressPercentage.value = value;
}

Future captureAndStitchImages() async {
List imagePaths = [];
final directory = await getApplicationDocumentsDirectory();
for (int i = 0; i < 10; i++) {
if (!isCapturing.value) break;

  final path = join(directory.path, '${DateTime.now().millisecondsSinceEpoch}.jpg');

  await cameraController.value?.takePicture();
  imagePaths.add(path);
  updateProgress((i + 1));
  await Future.delayed(const Duration(seconds: 100));
}

try {
  // Use opencv_dart to stitch images
  final stitchedImageBytes = await stitchImages(imagePaths);

  // Save the stitched image
  final stitchedImagePath = join(directory.path, 'stitched_panorama.jpg');
  final stitchedImageFile = File(stitchedImagePath);
  await stitchedImageFile.writeAsBytes(stitchedImageBytes);

  // Save to gallery
  await GallerySaver.saveImage(stitchedImagePath);

  // Upload the image using CarImagesListViewModel
  carImagesListViewModel.uploadImage(File(stitchedImagePath));

  // Navigate back to CarImagesScreen
  Get.back();
} catch (e) {
  isCapturing.value = false;
  print('Error stitching images: $e');
} finally {
  isCapturing.value = false;
  update();
}

}

Future<List> stitchImages(List imagePaths) async {
List images = [];

for (String path in imagePaths) {
  Mat image = imread(path);
  images.add(image);
}

var stitched = Stitcher.create().stitch(VecMat.fromList(images));

List<int> stitchedBytes = imencode('.jpg', stitched.$2).$2;

return stitchedBytes;

}

@OverRide
void onClose() {
cameraController.value?.dispose();
super.onClose();
}
}

and the screen where it's called:

class CameraPage extends GetView {
const CameraPage({super.key});

@OverRide
Widget build(BuildContext context) {
final Camera360Controller controller = Get.find();

return Scaffold(
  backgroundColor: Colors.transparent,
  appBar: AppBar(
    flexibleSpace: Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          colors: <Color>[
            Color(0xFF335ae9),
            Color(0xFF34baff),
          ],
        ),
      ),
    ),
    leading: IconButton(
      padding: EdgeInsets.zero,
      icon: const Icon(
        Icons.arrow_back_ios_rounded,
        color: Color(0xFFFFFFFF),
      ),
      onPressed: () => Get.back(),
    ),
    centerTitle: true,
    title: SvgPicture.asset(
      "assets/logo.svg",
      color: const Color(0xFFFFFFFF),
      height: 25,
      width: 30,
    ),
    elevation: 0,
  ),
  extendBodyBehindAppBar: true,
  body: Obx(() {
    if (controller.cameraController.value == null || !controller.cameraController.value!.value.isInitialized) {
      return const Center(child: CircularProgressIndicator());
    }

    return Stack(
      children: [
        CameraPreview(controller.cameraController.value!),
        Positioned(
          bottom: 20,
          left: 20,
          right: 20,
          child: Column(
            children: [
              LinearProgressIndicator(value: controller.progressPercentage.value / 100),
              const SizedBox(height: 20),
              controller.isCapturing.value
                  ? const Text('Capturing... Move the camera along the guidance line.')
                  : IconButton(
                onPressed: controller.startCapturing,
                icon: const Icon(Icons.camera),
              ),
            ],
          ),
        ),
        // Guidance line for panorama capturing
        Positioned(
          top: MediaQuery.of(context).size.height / 2,
          left: 0,
          right: 0,
          child: Container(
            height: 2,
            color: Colors.red,
          ),
        ),
      ],
    );
  }),
);

}
}

@rainyl
Copy link
Owner

rainyl commented Jul 29, 2024

A repoducible example please, e.g., a link to github repo, I do not want to copy from here to there, guess what plugins you are used and add the dependencies one by one.

@rainyl
Copy link
Owner

rainyl commented Jul 29, 2024

Allright, reproduced in the example app of abdelaziz-mahdy , refer to tensorflow/tensorflow#48001 (comment)

Add the following lines to section in android/app/src/main/AndroidManifest.xml

<uses-library android:name="libOpenCL.so" android:required="false"/>
<uses-library android:name="libOpenCL-pixel.so" android:required="false"/>

@GoxeeVladan
Copy link
Author

GoxeeVladan commented Jul 29, 2024

thanks, but now when i applied this i get the following error:

E/cv::error()(15188): OpenCV(4.10.0) Error: Requested object was not found (could not open directory: /data/app/~~bJrI2Zx43VlRNHN1PxjXow==/com.goxeedealer.intel_booth_app-qBA-5dV0TeF4sHiSKwsWpA==/base.apk!/lib/arm64-v8a) in glob_rec, file /home/runner/work/opencv.full/opencv.full/build/opencv/modules/core/src/glob.cpp, line 279

but after a minute or so it actually outputs the image, probably need some optimization on my end

@dirablue
Copy link

dirablue commented Aug 2, 2024

I face the same issue with this with Google Pixel 7
#179 (comment)

do you have any idea?


in my case, These are not needed and worked

<uses-library android:name="libOpenCL.so" android:required="false"/>
<uses-library android:name="libOpenCL-pixel.so" android:required="false"/>

@rainyl
Copy link
Owner

rainyl commented Aug 5, 2024

Again, a minimal reproducable example please.

@rainyl
Copy link
Owner

rainyl commented Aug 8, 2024

No response for a long time, I am going to close this issue.

Actually, any exceptions/errors, especially threw by native library, are almost likely to be the result of the users' incorrect usage or the bug of opencv itself, I recommend you search the error message first and then open an issue here.

@rainyl rainyl closed this as completed Aug 8, 2024
@rainyl rainyl mentioned this issue Aug 13, 2024
Closed
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants