I want to remove the letter artifacts "L:CC and Strin" from breast mammography using python. How could I get that done? this is my image
Here is one way to do that in Python/OpenCV.
Read the input
Convert to grayscale
Threshold
Dilate as mask
Apply mask to change white letters to black
Save the results
import cv2
import numpy as np
# read image
img = cv2.imread('mammogram_letters.png')
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# create mask
thresh = cv2.threshold(gray, 247, 255, cv2.THRESH_BINARY)[1]
# dilate mask
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
mask = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)
# apply change
result = img.copy()
result[mask == 255] = (0,0,0)
# save result
cv2.imwrite("mammogram_letters_thresh.png", thresh)
cv2.imwrite("mammogram_letters_mask.png", mask)
cv2.imwrite("mammogram_letters_blackened.png", result)
# show results
cv2.imshow("THRESH", thresh)
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
Threshold image:
Mask image:
Result:
You have to get pixel coordinate of the box containing test, if they are always the same my code will work.
from PIL import Image
im = Image.open('SqbIx.png')
img =im.load()
for i in range (73,116):
for j in range (36,57):
img[i,j]= (0, 0, 0)
im.save('mod.png')
Related
I'm new to python. I know basics about image-preprocessing. I don't know how to remove background and crop an image using OpenCV.
Here is the processing in Python/OpenCV for your new image.
Input:
import cv2
import numpy as np
# load image as grayscale
img = cv2.imread('Diabetic-Retinopathy_G_RM_151064169.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold input image
mask = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)[1]
# optional morphology to clean up small spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
# put mask into alpha channel of image
result = np.dstack((img, mask))
# save resulting masked image
cv2.imwrite('Diabetic-Retinopathy_G_RM_151064169_masked.png', result)
# display result, though it won't show transparency
cv2.imshow("mask", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result
Here is one way to do that in Python/OpenCV.
Read input
Convert to grayscale
Threshold and invert as mask
Put mask into alpha channel of input
Save result
Input:
import cv2
import numpy as np
# load image
img = cv2.imread('black_circle.png')
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
threshold = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)[1]
# invert so circle is white on black
mask = 255 - threshold
# put mask into alpha channel of image
result = np.dstack((img, mask))
# save resulting masked image
cv2.imwrite('black_circle_masked.png', result)
# display result, though it won't show transparency
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
Note: download the result to see the transparency.
How do I make it so everything in the image is in gray-scale except the orange cone. Using opencv python.
You can achieve your goal by using bitwise_and() function and thresholding.
Steps:
generate mask for the required region.(here thresholding is used but other methods can also be used)
extract required regions using bitwise_and (image & mask).
Add masked regions to get output.
Here's sample code:
import cv2
import numpy as np
img = cv2.imread('input.jpg')
# creating mask using thresholding over `red` channel (use better use histogram to get threshoding value)
# I have used 200 as thershoding value it can be different for different images
ret, mask = cv2.threshold(img[:, :,2], 200, 255, cv2.THRESH_BINARY)
mask3 = np.zeros_like(img)
mask3[:, :, 0] = mask
mask3[:, :, 1] = mask
mask3[:, :, 2] = mask
# extracting `orange` region using `biteise_and`
orange = cv2.bitwise_and(img, mask3)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
# extracting non-orange region
gray = cv2.bitwise_and(img, 255 - mask3)
# orange masked output
out = gray + orange
cv2.imwrite('orange.png', orange)
cv2.imwrite('gray.png', gray)
cv2.imwrite("output.png", out)
Results:
masked orange image
masked gray image
output image
Here is an alternate way to do that in Python/OpenCV.
Read the input
Threshold on color using cv2.inRange()
Apply morphology to clean it up and fill in holes as a mask
Create a grayscale version of the input
Merge the input and grayscale versions using the mask via np.where()
Save the results
Input:
import cv2
import numpy as np
img = cv2.imread("orange_cone.jpg")
# threshold on orange
lower = (0,60,200)
upper = (110,160,255)
thresh = cv2.inRange(img, lower, upper)
# apply morphology and make 3 channels as mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.merge([mask,mask,mask])
# create 3-channel grayscale version
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
# blend img with gray using mask
result = np.where(mask==255, img, gray)
# save images
cv2.imwrite('orange_cone_thresh.jpg', thresh)
cv2.imwrite('orange_cone_mask.jpg', mask)
cv2.imwrite('orange_cone_result.jpg', result)
# Display images
cv2.imshow("thresh", thresh)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
Threshold image:
Mask image:
Merged result:
I have a dataset that contains full width human images I want to remove all the backgrounds in those Images and just leave the full width person,
my questions:
is there any python code that does that ?
and do I need to specify each time the coordinate of the person object?
Here is one way using Python/OpenCV.
Read the input
Convert to gray
Threshold and invert as a mask
Optionally apply morphology to clean up any extraneous spots
Anti-alias the edges
Convert a copy of the input to BGRA and insert the mask as the alpha channel
Save the results
Input:
import cv2
import numpy as np
# load image
img = cv2.imread('person.png')
# convert to graky
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold input image as mask
mask = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY)[1]
# negate mask
mask = 255 - mask
# apply morphology to remove isolated extraneous noise
# use borderconstant of black since foreground touches the edges
kernel = np.ones((3,3), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# anti-alias the mask -- blur then stretch
# blur alpha channel
mask = cv2.GaussianBlur(mask, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)
# linear stretch so that 127.5 goes to 0, but 255 stays 255
mask = (2*(mask.astype(np.float32))-255.0).clip(0,255).astype(np.uint8)
# put mask into alpha channel
result = img.copy()
result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA)
result[:, :, 3] = mask
# save resulting masked image
cv2.imwrite('person_transp_bckgrnd.png', result)
# display result, though it won't show transparency
cv2.imshow("INPUT", img)
cv2.imshow("GRAY", gray)
cv2.imshow("MASK", mask)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Transparent result:
How To Add Color Inside The Edges - Python (OpenCV)
I am Trying to remove the background From this image ,
Partatily i Succeed From the help of Internet,I created edge of image using canny,
But i want to add white background inside the object edge (inside the object edges) ,
For better Output
This Is the code for Remove Background ,That i Created
Inputed Image
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('img/aa.jpg')
original=img.copy()
l = int(max(5, 6))
u = int(min(6, 6))
edges = cv.GaussianBlur(img, (21, 51),3)
edges = cv.cvtColor(edges , cv.COLOR_BGR2GRAY)
mask = np.zeros(img.shape, dtype=np.uint8)
edges = cv.Canny(edges,l,u)
edges = cv.dilate(edges, None)
edges = cv.erode(edges, None)
_,thresh=cv.threshold(edges,0,255,cv.THRESH_BINARY + cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5,5))
morphed = cv.morphologyEx(thresh, cv.MORPH_CLOSE, kernel)
dilate=cv.dilate(morphed, None, iterations = 1) #change iteration
mask=dilate
(cnts, _) =cv.findContours(dilate, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
for contour in cnts:
# (x, y, w, h) = cv.boundingRect(contour)
if cv.contourArea(contour) < 2000:
continue
cv.drawContours(mask ,contour, -1, (255, 255, 255), 3)
result = cv.bitwise_and(original, original, mask=mask)
result[dilate==0] = (0,0,0)
img1=cv.resize(mask,(600,400))
cv.imshow(' Image', img1)
img=cv.resize(result,(600,400))
cv.imshow('Original Image', img)
cv.waitKey()
OUTPUT
Any other thoughts would be greatly appreciated!
Here is how I would do that in Python/OpenCV.
Read the input
Convert to HSV color space
Apply color thresholding on the background color in hsv to create a mask
Invert the mask
Apply morphology to fill the holes and remove extraneous regions
Use mask to make background of images white
Input:
import cv2
import numpy as np
# load image and get dimensions
img = cv2.imread("man_face.jpeg")
# convert to hsv
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# threshold using inRange
range1 = (50,0,50)
range2 = (120,120,170)
mask = cv2.inRange(hsv,range1,range2)
# invert mask
mask = 255 - mask
# apply morphology closing and opening to mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
result = img.copy()
result[mask==0] = (255,255,255)
# write result to disk
cv2.imwrite("man_face_mask.png", mask)
cv2.imwrite("man_face_white_background.jpg", result)
# display it
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Mask image:
Result:
I need to remove the gray drawing from the image background and only need symbols drawn over it.
Here is my code to do that using morphologyEx but it did not remove the entire gray drawing that is in background.
img_path = "images/new_drawing.png"
img = cv2.imread(img_path)
kernel = np.ones((2,2), dtype=np.uint8)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
cv2.imshow('Without background',result);
cv2.waitKey(0)
cv2.destroyAllWindows()
I tried this also and got expected results in grayscale but unable to convert it to BGR.
Here is my code
img = cv2.imread('images/new_drawing.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
med_blur = cv2.medianBlur(gray_img, ksize=3)
_, thresh = cv2.threshold(med_blur, 190, 255, cv2.THRESH_BINARY)
blending = cv2.addWeighted(gray_img, 0.5, thresh, 0.9, gamma=0)
cv2.imshow("blending", blending);
Also i used contours to identify symbols and draw them to white image but problem is that it also identify background drawing that i don't want.
Input image
Expected output image
Also the drawing will be always in gray color as in image.
Please help me out to get better result.
You are almost there...
Instead of using cv2.inRange to "catch" the non-gray pixel I suggest using cv2.inRange for catching all the pixels you want to change to white color:
mask = cv2.inRange(hsv, (0, 0, 100), (255, 5, 255))
The hue range is irrelevant.
The saturation is close to zero (shades of gray).
The brightness excludes the black pixels (you like to keep).
In order to get a nicer solution, I also used the following additional stages:
Build a mask of non-black pixels:
nzmask = cv2.inRange(hsv, (0, 0, 5), (255, 255, 255))
Erode the above mask:
nzmask = cv2.erode(nzmask, np.ones((3,3)))
Apply and operation between mask and nzmask:
mask = mask & nzmask
The above stages keeps the gray pixels around the black text.
Without the above stages, the black text gets thinner.
The last stage is replacing mask pixels with white:
new_img = img.copy()
new_img[np.where(mask)] = 255
Here is the code:
import numpy as np
import cv2
img_path = "new_drawing.png"
img = cv2.imread(img_path)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (0, 0, 100), (255, 5, 255))
cv2.imshow('mask before and with nzmask', mask);
# Build mask of non black pixels.
nzmask = cv2.inRange(hsv, (0, 0, 5), (255, 255, 255))
# Erode the mask - all pixels around a black pixels should not be masked.
nzmask = cv2.erode(nzmask, np.ones((3,3)))
cv2.imshow('nzmask', nzmask);
mask = mask & nzmask
new_img = img.copy()
new_img[np.where(mask)] = 255
cv2.imshow('mask', mask);
cv2.imshow('new_img', new_img);
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
Here is one way to do that in Python/OpenCV.
Read the input
Convert to HSV and separate channels
Threshold the saturation channel
Threshold the value channel and invert
Combine the two threshold images as a mask
Apply the mask to the input to write white where the mask is black
Save the result
Input:
import cv2
import numpy as np
# read image
img = cv2.imread('symbols.png')
# convert image to hsv colorspace
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
# threshold saturation image
thresh1 = cv2.threshold(s, 92, 255, cv2.THRESH_BINARY)[1]
# threshold value image and invert
thresh2 = cv2.threshold(v, 128, 255, cv2.THRESH_BINARY)[1]
thresh2 = 255 - thresh2
# combine the two threshold images as a mask
mask = cv2.add(thresh1,thresh2)
# use mask to remove lines in background of input
result = img.copy()
result[mask==0] = (255,255,255)
# display IN and OUT images
cv2.imshow('IMAGE', img)
cv2.imshow('SAT', s)
cv2.imshow('VAL', v)
cv2.imshow('THRESH1', thresh1)
cv2.imshow('THRESH2', thresh2)
cv2.imshow('MASK', mask)
cv2.imshow('RESULT', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save output image
cv2.imwrite('symbols_thresh1.png', thresh1)
cv2.imwrite('symbols_thresh2.png', thresh2)
cv2.imwrite('symbols_mask.png', mask)
cv2.imwrite('symbols_cleaned.png', result)
Saturation channel thresholded:
Value channel thresholded and inverted:
Mask:
Result: