I need to create some spots on an image. The spots are of irregular shape (mainly I was trying to add a big circle then trying to add smaller circles on the edges of the big circle so it gets an “irregular” circular shape). Here I just showed one circle in the example. As I have a directory full of images, the size, the location, and the number of the spots need to be varied for every image. What I tried is given here:
JavaScript
x
23
23
1
import glob
2
import cv2
3
import numpy as np
4
import random
5
6
7
count = 0
8
cv_img = []
9
for img in glob.glob('Lenna_(test_image).png'):
10
n = cv2.imread(img)
11
for i in range(random.randint(1, 5)):
12
13
c1 = random.randrange(75,200,1)
14
c2 = random.randrange(70,350,1)
15
r1 = random.randint(8,18)
16
17
n1_img = cv2.circle(n,(c1,c2),(r1),(255,255,255),-1, lineType = 4)
18
19
20
cv_img.append(n1_img)
21
cv2.imwrite('result.png',n1_img)
22
count = count+1
23
But I want to add something like this. I did it with paint. This is the thing I want to add on the image
Advertisement
Answer
Here is the full code to add the white blobs with a black border onto some image in Python/OpenCV.
Input:
JavaScript
1
69
69
1
import cv2
2
import skimage.exposure
3
import numpy as np
4
from numpy.random import default_rng
5
6
# read input image
7
img = cv2.imread('lena.jpg')
8
height, width = img.shape[:2]
9
10
# define random seed to change the pattern
11
seedval = 75
12
rng = default_rng(seed=seedval)
13
14
# create random noise image
15
noise = rng.integers(0, 255, (height,width), np.uint8, True)
16
17
# blur the noise image to control the size
18
blur = cv2.GaussianBlur(noise, (0,0), sigmaX=15, sigmaY=15, borderType = cv2.BORDER_DEFAULT)
19
20
# stretch the blurred image to full dynamic range
21
stretch = skimage.exposure.rescale_intensity(blur, in_range='image', out_range=(0,255)).astype(np.uint8)
22
23
# threshold stretched image to control the size
24
thresh = cv2.threshold(stretch, 175, 255, cv2.THRESH_BINARY)[1]
25
26
# apply morphology open and close to smooth out and make 3 channels
27
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
28
mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
29
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
30
mask = cv2.merge([mask,mask,mask])
31
32
# add mask to input
33
result1 = cv2.add(img, mask)
34
35
# use canny edge detection on mask
36
edges = cv2.Canny(mask,50,255)
37
38
# thicken edges and make 3 channel
39
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
40
edges = cv2.morphologyEx(edges, cv2.MORPH_DILATE, kernel)
41
edges = cv2.merge([edges,edges,edges])
42
43
# merge edges with result1 (make black in result where edges are white)
44
result2 = result1.copy()
45
result2[np.where((edges == [255,255,255]).all(axis=2))] = [0,0,0]
46
47
# add noise to result where mask is white
48
noise = cv2.merge([noise,noise,noise])
49
result3 = result2.copy()
50
result3 = np.where(mask==(255,255,255), noise, result3)
51
52
# save result
53
cv2.imwrite('lena_random_blobs1.jpg', result1)
54
cv2.imwrite('lena_random_blobs2.jpg', result2)
55
cv2.imwrite('lena_random_blobs3.jpg', result3)
56
57
# show results
58
cv2.imshow('noise', noise)
59
cv2.imshow('blur', blur)
60
cv2.imshow('stretch', stretch)
61
cv2.imshow('thresh', thresh)
62
cv2.imshow('mask', mask)
63
cv2.imshow('edges', edges)
64
cv2.imshow('result1', result1)
65
cv2.imshow('result2', result2)
66
cv2.imshow('result3', result3)
67
cv2.waitKey(0)
68
cv2.destroyAllWindows()
69
Result1 (white blobs):
Result2 (white blobs with black border):
Result3 (noise blobs with black border):