i was working on a project that requires me to remove a specific type of watermark from the background of some pictures (usually stem related, as this is an education project.) now, i tried to remove the watermark from the following picture to start with:
this is the picture i tried to remove it from
you’ll probably have to zoom in to see it; but it says examgoal
however, for some reason, the output i got, though it was far from ideal, was tinted in blue. i have no idea why this happened and have been working on this for hours; but couldnt find a solution
i ran the following code on google colab; which did kinda (very poorly, though) get rid of the watermark. for your reference, i used matplotlib, numpy as well as cv2.
i would really appreciate some help on how to go about this, because i’m also trying to generalize this process for multiple pictures.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
uploaded = files.upload()
for filename in uploaded.keys():
print(f'Uploaded file name: {filename}')
image_path = filename
image = cv2.imread(image_path)
if image is None:
print(f"Error: Unable to load image at {image_path}")
else:
print("Image loaded successfully")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
enhanced = cv2.equalizeHist(gray)
adaptive_thresh = cv2.adaptiveThreshold(enhanced, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
kernel = np.ones((3, 3), np.uint8)
morph = cv2.morphologyEx(adaptive_thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
mask = cv2.bitwise_not(morph)
result = cv2.inpaint(image, mask, 3, cv2.INPAINT_TELEA)
plt.figure(figsize=(15, 15))
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.subplot(1, 2, 2)
plt.title('Image without Watermark')
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.show()
Adi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
11
As correctly suggested by @TinoD, the problem is caused by the fact that you are treating the image as RGB/BGR, but it also has an alpha channel that get lost with your implementation.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
uploaded = files.upload()
for filename in uploaded.keys():
print(f'Uploaded file name: {filename}')
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
image_original = image.copy()
if image is None:
print(f"Error: Unable to load image at {image_path}")
else:
print("Image loaded successfully")
# Split RGB and alpha channel
rgb = image[:, :, :-1]
alpha = image[:, :, -1]
# Process the RGB channels
gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
enhanced = cv2.equalizeHist(gray)
adaptive_thresh = cv2.adaptiveThreshold(enhanced, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
kernel = np.ones((3, 3), np.uint8)
morph = cv2.morphologyEx(adaptive_thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
mask = cv2.bitwise_not(morph)
result = cv2.inpaint(rgb, mask, 3, cv2.INPAINT_TELEA)
# Re-apply the original alpha channel
result = cv2.cvtColor(result, cv2.COLOR_RGB2RGBA)
result[:, :, -1] = alpha
plt.figure(figsize=(15, 15))
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(image_original, cv2.COLOR_BGRA2RGBA))
plt.subplot(1, 2, 2)
plt.title('Image without Watermark')
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGRA2RGBA))
plt.show()
You will get your images with the expected background color.
As you can see, this solves you problem with matplotlib
‘s coloring of your data.
For the watermark removal part, as @Christoph Rackwitz mentioned, you will have an hard time getting help to infringe someone else’s copyright on SO.
Here is your picture’s channels shown individually (BGRA):
As you can see, the colors contain almost no information. The text is encoded in the alpha channel. That is as it should be, for the alpha channel to work properly.
When OpenCV loads an image, it discards the alpha channel by default. You’re getting just the first three channels. That looks like so:
So no, matplotlib is not to blame. Matplotlib does not apply any coloring here. Nor is there a mismatch of channel orders. You correctly handled that (cvtColor
with BGR2RGB
).
This is purely a consequence of OpenCV discarding the alpha channel by default. You have to load the image with cv.IMREAD_UNCHANGED
to get it.
Even then, OpenCV’s cv.imshow
doesn’t know how to handle it. Matplotlib does.