4

I am very new to opencv and deep learning using python. I am trying to remove watermark/logo from an image. I am able to find location of watermark by finding the location of cropped watermark image in the original image in the image which is constant for all the images. I need to remove found watermark.

Here is original image:[![original_image.jpeg][1]][1] Original image2:[![enenter code hereter image description here][2]][2] Original image3:[![enter image description here][3]][3]

Cropped watermark image from original image: [![cropped_image.jpeg][4]][4]

Located watermark in the image: [![Located watermark][5]][5] I tried various code which uses tensorflow/deep learning below which din't generalise and given various error while running them.

For example I tried automatic-watermark-detection( https://github.com/rohitrango/automatic-watermark-detection) but it din't work. The crop_watermark() function in this library was not working for my image.It was cropping some other part of the image which is not water mark there was many other issue with code as well.

Similary I tried many other deep learning library with no luck.

I was also thinking to try cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA) but I don't have mask image. I have only one image with watermark on it as below so not able to use inpaint() function as well.

Currently trying below simple code to find out exact location of the watermark in the image (by cropping the water mark manually and finding the location in the original image).

import numpy as np
import cv2 
img = cv2.imread('original_image.jpeg')

print(img.shape)

h,w,c =  img.shape

logo = cv2.imread("cropped_image.jpeg")
print(logo.shape)
hl,wl,cl  =  logo.shape

x1 = int(w/2-wl/2)
y1 = int(h/2-hl)
x2 = int(w/2+wl/2)
y2 =  int(h/2)
cv2.rectangle(img, (x1, y1), (x2, y2), (255,0,0), 2)

cv2.imwrite("my.png",img)
cv2.imshow("lalala", img)

Above code is able to find correct coordinates of watermark. From here onwards I don't know how to proceed to remove watermark. It will be great if you can provide some sample code as well along with concept.

Thank you for help.

Abhay Kumar
  • 113
  • 1
  • 1
  • 10
  • Have you looked at this: https://stackoverflow.com/questions/32125281/removing-watermark-out-of-an-image-using-opencv?rq=1 – godot Apr 23 '19 at 12:23
  • I seen that but it was in c++, I din't tried. Trying to implement the concept mentioned in accepted answer now. – Abhay Kumar Apr 23 '19 at 12:26
  • Morphological filtering giving same image for my image unlike mentioned in the tutorial. Can't proceed with next steps. – Abhay Kumar Apr 23 '19 at 12:44

1 Answers1

3

You can try inpaint() function of the OpenCV contrib_module, which you first need to create a mask and indicate the area where the logo is there on the image, then pass the image and the mask, and then the result will be stored in the destination image.

@param src source image, it could be of any type and any number of channels from 1 to 4. In case of
3- and 4-channels images the function expect them in CIELab colorspace or similar one, where first
color component shows intensity, while second and third shows colors. Nonetheless you can try any
colorspaces.
@param mask mask (CV_8UC1), where non-zero pixels indicate valid image area, while zero pixels
indicate area to be inpainted
@param dst destination image
@param algorithmType see xphoto::InpaintTypes
*/
CV_EXPORTS_W void inpaint(const Mat &src, const Mat &mask, Mat &dst, const int algorithmType);

Some hints to create the mask: When you created the mask image by some tools (image editor), the background must be in black and the logo area must be in white. And then when the image created before used it as the mask, you should first convert the image to gray, and then threshold the image with THRESH_BINARY flag.


Update: The implementation, this is the code, it is in C++, but you can consider the steps and it is all the same.

cv::namedWindow("Original_Image", cv::WINDOW_FREERATIO);
cv::namedWindow("Result", cv::WINDOW_FREERATIO);
cv::Mat originalImg = cv::imread("y25av.jpg");
cv::Mat mask = cv::imread("mask.jpg");

// to gray
cv::Mat gray;
cv::cvtColor(mask, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, mask, 180, 255, cv::THRESH_BINARY);

cv::Mat dst;
cv::inpaint(originalImg, mask, dst, 10, cv::INPAINT_TELEA);

cv::imshow("Original_Image", originalImg);
cv::imshow("Result", dst);
cv::waitKey();

Your original image:

enter image description here

The mask used:

enter image description here

The final result:

enter image description here

Bahramdun Adil
  • 5,907
  • 7
  • 35
  • 68
  • 1
    Thank you for answering. How to create mask? I have only one image with watermark. Please help me with this step. – Abhay Kumar Apr 23 '19 at 12:36
  • You should create a mask by some tools, like PhotoShop, and then use that mask remove the logo. – Bahramdun Adil Apr 23 '19 at 12:41
  • What would be background color of the mask with logo? – Abhay Kumar Apr 23 '19 at 12:47
  • The mask can be one channel, the background must be black (0) and the logo area must be in white (255). – Bahramdun Adil Apr 23 '19 at 12:48
  • 1
    @AbhayKumar I have edited the answer, you can have a look to updated part. – Bahramdun Adil Apr 23 '19 at 12:53
  • I never used photoshop or an image editor. Should I use an original image to create the mask with logo written like similar to original image or I should create a mask from scratch and write text logo in similar style on the image? – Abhay Kumar Apr 23 '19 at 13:01
  • Can you help me to create? Thanks . I could have use this function at 2 days back itself. They only hurdle was to create the mask. – Abhay Kumar Apr 23 '19 at 13:09
  • 1
    @AbhayKumar I will try to do this, I will update the answer, you should check it later. – Bahramdun Adil Apr 23 '19 at 13:10
  • Ok Thank you. Thanks a lot for the help. I am up voting the answer and will accept once I am able to run it. – Abhay Kumar Apr 23 '19 at 13:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192273/discussion-between-abhay-kumar-and-bahramdun-adil). – Abhay Kumar Apr 23 '19 at 14:11
  • @AbhayKumar The answer has been updated, and you can have a look again. Hope it is what you want! Good Luck! – Bahramdun Adil Apr 23 '19 at 14:12
  • Code is not working for all the image except the one you tried. I have updated the question with two more test image on which same code is not working. What we can do to generalise the code? Thanks. – Abhay Kumar Apr 24 '19 at 13:56
  • 1
    I have told you that the created mask must fit 100% logo area, yesterday I don't have much time to do it for you, but because you don't know to create so, I created one for you, then give you the simple code. And you just provided only one example image, I have already done it for you. Anyway, now what you can create a 100% fitted mask, and then you can play with `inpaintRadius` and `flags`, try different values and flags and see the result. – Bahramdun Adil Apr 24 '19 at 16:01
  • Thanks a ton for your hardwork and effort. Tried with flag and radius as I mentioned in the questions. Using your same logo mask and with same dimension of test image . Not working for others :( – Abhay Kumar Apr 24 '19 at 16:07
  • One last question support I found correct radius for one of the image. Will this radius be constant for all kinds of coloured image? – Abhay Kumar Apr 24 '19 at 16:08
  • This depends on some of these situations: 1. The area where you want to remove, the thinner the better result, but the logo in your image seems a little bit OK. 2. The image background color complexity, the more complex the worse result because of that the first image works well because of the less background color complexity. So there is no one best value to satisfy all the situations, so because of this there are parameters to fine tune and find the best one for your task. – Bahramdun Adil Apr 24 '19 at 16:44
  • What if the mark you want to remove is in a different area on each picture? I have digitized slides that have this weird bird shape on them - it's not in the same place on each slide, but it is the same shape. Can you use this same method? (I haven't tried because I'm still learning and looking for answers). – DataGirl Jul 18 '20 at 12:50
  • 1
    @DataGirl It must fit the exact position, if you can calculate the movement offset of the logo in each slide, then you move the mask to fit the position in each slide. – Bahramdun Adil Jul 18 '20 at 15:09