i am using python with opencv and numpy, to detect stars in astronomical for example this one1 images. Using template matching I have got it to detect stars with a threshold (click the 2) 2 by drawing a rectangle around a star template. My next goal is to essentially "remove" the stars from the image.
To do this, I have tried blurring the image with different methods, cv2.blur etc, but it doesn't create the effect i am looking for. My next idea was to get rgb data from pixels around the star, average them out, and color in the star with the selected colour. Is this the best option and how would i do this?
my code is as below.
import cv2
import numpy as np
import time
start = time.time()
threshold = 0.4
image = cv2.imread('lag.jpg')
imageG = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#cv2.imshow('original', image)
#cv2.imshow('greyscale', imageG)
template = cv2.imread('template.jpg', 0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(imageG,template,cv2.TM_CCOEFF_NORMED)
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
a = cv2.rectangle(image, pt, (pt[0] + w, pt[1] + h), (0,0,255), 1)
cv2.imshow('lag.jpg', image)
end = time.time()
final = end - start
print(final)
cv2.waitKey(0)
cv2.destroyAllWindows()
You may create a mask, and use cv2.inpaint for replacing the selected "mask area" using the pixel near the area boundary.
Since you didn't post 'template.jpg', I created the following one:

Building a mask by drawing filled rectangles on zeros image:
mask = np.zeros_like(imageG)
for pt in zip(*loc[::-1]):
#a = cv2.rectangle(image, pt, (pt[0] + w, pt[1] + h), (0,0,255), 1)
cv2.rectangle(mask, (pt[0]+3, pt[1]+3), (pt[0]+w-3, pt[1]+h-3), 255, -1) # Reduce the size of the rectangle by 3 pixels from each side.
Note: I used cv2.rectangle for keeping your original code, but I think circles may by better in your case.
Using inpaint for removing the masked area:
image = cv2.inpaint(image, mask, 2, cv2.INPAINT_NS)
You may tune the parameters.
Here is the complete code:
import cv2
import numpy as np
import time
start = time.time()
threshold = 0.4
image = cv2.imread('lag.jpg')
imageG = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#template = cv2.imread('template.jpg', 0)
template = cv2.imread('template.png', 0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(imageG,template,cv2.TM_CCOEFF_NORMED)
loc = np.where( res >= threshold)
mask = np.zeros_like(imageG)
for pt in zip(*loc[::-1]):
#a = cv2.rectangle(image, pt, (pt[0] + w, pt[1] + h), (0,0,255), 1)
cv2.rectangle(mask, (pt[0]+3, pt[1]+3), (pt[0]+w-3, pt[1]+h-3), 255, -1) # Reduce the size of the rectangle by 3 pixels from each side
image = cv2.inpaint(image, mask, 2, cv2.INPAINT_NS)
cv2.imshow('lag.jpg', image)
cv2.imshow('mask', mask)
end = time.time()
final = end - start
print(final)
cv2.waitKey(0)
cv2.destroyAllWindows()
Results:
mask:

image (after inpaint):

Original image (for comparison):

You may improve the solution using few sizes of rectangles (or circles) - use larger rectangles for covering the larger stars.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With