react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

❓ Apply filter to photos

Open Angelk90 opened this issue 2 years ago • 24 comments

Question

Hi @mrousavy , I had a look at the documentation, I was wondering if using the following library together with FrameProcessor, it would be possible to be able to do something similar as seen in the images.

In short, in real time you can apply filters to the photos/videos you make, doing everything by js, not touching the android/swift code.

image image

What I tried

No response

VisionCamera Version

2.11.2

Additional information

Angelk90 avatar Jan 09 '22 19:01 Angelk90

Hey! This seems very similar as #526.

In theory; it is possible to build such an interface, but that requires a lot of my free time, which I currently don't have. I'm running a company. If you, or anyone else reading this comment, is interested in this becoming reality, consider a collaboration with me and my app development/consulting agency "Margelo": Contact me at [email protected]

mrousavy avatar Jan 10 '22 08:01 mrousavy

Actually a hacky solution right now would be to use Frame Processors to detect the faces, and then draw the face-filters ontop of the Camera using react-native-skia. This should be very performant and happen in realtime, and you can then just take a screenshot of the view (see this lib) to "capture" it.

A real solution would be to offer an intermediate layer to draw upon, whether it's 3D AR, or 2D overlays, which is also part of the capture pipeline (photo & video). Again, I don't have the free time to work on this, but I have some ideas how that can be implemented in C++ for a fast and easy way of drawing 3D/2D filters straight from JS.

mrousavy avatar Jan 10 '22 08:01 mrousavy

cc @wcandillon & @chrfalch

mrousavy avatar Jan 10 '22 08:01 mrousavy

let's do it 🙌🏼

wcandillon avatar Jan 10 '22 08:01 wcandillon

What do you think about opening a discussion about a possible implementation?

@mrousavy: So we can discuss any ideas that come to mind.

Actually a hacky solution right now would be to use Frame Processors to detect the faces, and then draw the face-filters ontop of the Camera using react-native-skia. This should be very performant and happen in realtime, and you can then just take a screenshot of the view (see this lib) to "capture" it.

Hacky Solution: I too had thought of a solution like this. But doing such a thing is not enough: https://mrousavy.com/react-native-vision-camera/docs/guides/frame-processors#interacting-with-frame-processors

Using frame-processors instead of drawing a rectangle, put an image on top. What should react-native-skia do in this case?

The problem with this is how to take the photo with the filter together, using the screenshot method is not that convincing me.

We think of different photo sizes or different ratios.

It is an excellent solution only that it does not completely convince me.

A real solution would be to offer an intermediate layer to draw upon, whether it's 3D AR, or 2D overlays, which is also part of the capture pipeline (photo & video). Again, I don't have the free time to work on this, but I have some ideas how that can be implemented in C++ for a fast and easy way of drawing 3D/2D filters straight from JS.

I would be very curious to hear all your proposals, I cannot tell you that I will be able to contribute to the development, I do not know if I still have the skills.

@wcandillon : I found the following project I don't know if it can help you as inspiration, there are some masks you could also use: Github

Angelk90 avatar Jan 10 '22 09:01 Angelk90

Skia will support off-screen drawing very soon - and it should be possible to take the bytes from the current frame, create a new surface, draw on the surface and then return the bytes back to the frame processor. Would this be a solution we could work with? Maybe I can discuss this with @mrousavy and see if we can find a way to get this working?

chrfalch avatar Jan 10 '22 09:01 chrfalch

@mrousavy : Frame Processor to detect faces, does it recognize even if there are multiple faces?

For example, if there are three or more people in a shot, do you recognize them all?

Angelk90 avatar Jan 10 '22 09:01 Angelk90

  1. Frame Processors detect the face, and return the bounding box.
  2. RN Skia draws a face filter at the bounding box coordinates, smoothly and at 60 FPS, and running on the Frame Processor Thread, ontop of the Camera View
  3. You then take a "screenshot" of the view.

it does not completely convince me

@Angelk90 Well of course, I said it's a hacky solution right now.

Skia will support off-screen drawing very soon

@chrfalch that's exactly what's needed for this. Let's discuss this in DMs

does it recognize even if there are multiple faces?

@Angelk90 I am not sure if you understand Frame Processors correctly. It is up to you to implement the face detection, and there are tons of implementations for that out there. Frame Processors is an API that allows you to easily create those plugins and use them from JS, with VisionCamera. So if e.g. MLKit allows you to detect multiple faces, then use that.

mrousavy avatar Jan 10 '22 09:01 mrousavy

I'm also interesting in implementing a "Green Screen" effect, I think the method will be different in that we will output a mask from the ML model and subtract the rest of the image. I did a tiny bit of research into RN Skia but couldn't find a "subtract" feature, do you guys think this is possible with current RN packages?

image

Green screen effect:

jsindos avatar Feb 07 '22 00:02 jsindos

@jsindos : What did you use to make this "Green screen effect"? Java(android)?

Angelk90 avatar Feb 07 '22 09:02 Angelk90

Hey yes I think this is possible using RN Skia - there's a prop (called draw mode or something) which you can set to SRC_OUT or DST_OUT and it will only draw where the mask is transparent (cc @chrfalch)

mrousavy avatar Feb 07 '22 10:02 mrousavy

Ok cool thanks @mrousavy.

Basically my plan is to use the PyTorch implementation of https://github.com/PeterL1n/RobustVideoMatting (not 100% sure if this will be performant on mobile phones yet), and save a TorchScript copy of the model.

I'll then write the Objective-C equivalent code of:

bgr = torch.tensor([.47, 1, .6]).view(3, 1, 1).cuda()  # Green background.

for src in YOUR_VIDEO:  # src can be [B, C, H, W] (Batch, Channel, Height, Width) or [B, T, C, H, W]
    fgr, pha, *rec = model(src, *rec, downsample_ratio=0.25)
    writer.write(fgr * pha + bgr * (1 - pha)) # writes to the video, this will have to be moved to RN Skia?

where fgr, pha are the foreground and alpha predictions.

And package this up as a Frame Processor Plugin (not 100% sure how to do this).

jsindos avatar Feb 08 '22 02:02 jsindos

Yep that should work! I'd recommend creating this in your private project first (just a single file per platform), then extracting it into a public package once it works for you. (See community plugins for reference)

This is maybe an interesting use-case @raedle? 😄

mrousavy avatar Feb 08 '22 11:02 mrousavy

@mrousavy could be interesting, yes. It would require video support, which PyTorch Live currently doesn't have, but something we'd like to add in the future :)

raedle avatar Feb 11 '22 07:02 raedle

It's not very relevant, but I have developed a library where you can use AR filters like beauty filters and face filters for React-Native, I hope it will be useful to someone: https://github.com/ridvanaltun/react-native-deepar

ridvanaltun avatar Jun 28 '22 21:06 ridvanaltun

Hi my friends by code,are there any news and someone know how to do it?

bi885895 avatar Jul 18 '22 21:07 bi885895

Hey everyone! I'm working on bringing this to iOS in #1198 and have a plan for an intermediate drawing layer for Android using OpenGL too 🙌

thomas-coldwell avatar Aug 24 '22 12:08 thomas-coldwell

i want to add filters like snapchat and instagram and reels on face filters like animals faces or etc... anyonce can guide me @Angelk90 @raedle @mrousavy .

shyammanek avatar Jul 05 '23 18:07 shyammanek

Hey everyone - this is a pretty old issue but I've actually finished the implementation for this using RN Skia, but I decided to not merge it into VisionCamera V3 since that overcomplicated the codebase by a lot and made VisionCamera heavier for everyone (including the people who don't use the Skia features).

So I'm preparing to release this as a separate package or fork soon.

mrousavy avatar Sep 30 '23 09:09 mrousavy

@mrousavy : Wouldn't it be possible to make it possible to include it as an external lib?

<Camera
      style={StyleSheet.absoluteFill}
      device={device}
      isActive={true}
      filter={filter}  // Here
    />

Angelk90 avatar Oct 02 '23 13:10 Angelk90

@mrousavy Any updates on the fork? Looking to try it out if there is a repo available. Thanks for everything you do.

1337mus avatar Dec 03 '23 07:12 1337mus

@mrousavy Any updates on the fork? I also need that feature

disleem1337 avatar Dec 12 '23 13:12 disleem1337

no not yet

mrousavy avatar Dec 12 '23 18:12 mrousavy

@mrousavy It seems like a combination of rodgomesc/vision-camera-face-detector and something like Skia would be the way to go, right? What would be the added benefit of #1198? Do we still need it for such an application?

kamilafsar avatar Jan 24 '24 10:01 kamilafsar

See https://github.com/mrousavy/react-native-vision-camera/pull/2727 👀

mrousavy avatar Apr 12 '24 12:04 mrousavy

@mrousavy : You can create a usage example?

Angelk90 avatar Apr 12 '24 14:04 Angelk90

there is one in the PR.

mrousavy avatar Apr 12 '24 15:04 mrousavy