I want to detect all the curves in an image. I'm using python. I tried below code but it didn't detect all the curves in the image (red dotted circles). Can anybody please help to to know the problem?
import numpy as np
import matplotlib.pyplot as plt
import cv2
from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
image = cv2.imread('s5.png',0)
edges = canny(image, sigma=6, low_threshold=35, high_threshold=50)
hough_radii = np.arange(20, 35, 2)
hough_res = hough_circle(edges, hough_radii)
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii,
total_num_peaks=3)
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(10, 4))
image = color.gray2rgb(image)
for center_y, center_x, radius in zip(cy, cx, radii):
circy, circx = circle_perimeter(center_y, center_x, radius)
image[circy, circx] = (220, 20, 20)
ax.imshow(image, cmap=plt.cm.gray)
plt.show()
This is the output:
Related
I have some microscopic images where there are precipitates in single states and in some we have in horizontal or vertical lines. Now how should I remove these lines?
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage as ndi
import cv2
import math
from skimage import (
color, feature, filters, measure, morphology, segmentation, util
)
# Sample1 - T61
image = cv2.imread(r"C:\Users\Stelle1.tif",cv2.IMREAD_GRAYSCALE)
assert not isinstance(image,type(None)), 'image not found'
fig, ax = plt.subplots()
ax.imshow(image, cmap='gray')
ax.axis('off')
plt.imshow()
click to view the image
fig, ax = plt.subplots(figsize=(5, 5))
qcs = ax.contour(image, origin='image')
ax.axis('off')
plt.show()
thresholds = filters.threshold_multiotsu(image, classes=3)
regions = np.digitize(image, bins=thresholds)
fig, ax = plt.subplots(ncols=2, figsize=(10, 5))
ax[0].imshow(image)
ax[0].set_title('Original')
ax[0].axis('off')
ax[1].imshow(regions)
ax[1].set_title('Multi-Otsu thresholding')
ax[1].axis('off')
plt.show()
cells = image > thresholds[0]
dividing = image > thresholds[1]
labeled_cells = measure.label(cells)
labeled_dividing = measure.label(dividing)
naive_mi = labeled_dividing.max() / labeled_cells.max()
print(naive_mi)
higher_threshold = 100
dividing = image > higher_threshold
smoother_dividing = filters.rank.mean(util.img_as_ubyte(dividing),
morphology.disk(4))
binary_smoother_dividing = smoother_dividing > 20
fig, ax = plt.subplots(figsize=(5, 5))
ax.imshow(binary_smoother_dividing)
ax.set_title('Dividing precipitate')
ax.axis('off')
plt.show()
click to view the image
Here is what I got if I increase the higher_threshold = 100, I will lose the ellipse shape precipitate where I need to count the area and other properties. Can you suggest some solution that the algorithm should not detect the line shape precipitates?
Have you thought about using something like a hough transform to detect straight lines?:
https://scikit-image.org/docs/dev/auto_examples/edges/plot_line_hough_transform.html
I basically lifted this straight from the above tutorial and got some pretty decent out of the box results.
from skimage import io
from skimage.transform import probabilistic_hough_line
from skimage.feature import canny
img = io.imread('GsSj9.png', as_gray=True) # read in the image
edges = canny(img) # use canny filter to detect edges
lines = probabilistic_hough_line(edges, threshold=20, line_length=20, line_gap=3)
# make plot of image and probabilistic_hough_line
fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
ax = axes.ravel()
ax[0].imshow(img)
ax[0].set_title('image')
ax[1].imshow(img * 0)
for line in lines:
p0, p1 = line
ax[1].plot((p0[0], p1[0]), (p0[1], p1[1]))
ax[1].set_xlim((0, img.shape[1]))
ax[1].set_ylim((img.shape[0], 0))
ax[1].set_title('Probabilistic Hough')
You would still need to figure out a good way to make a binary image from the transform lines but it could be useful in your endeavor.
I have a data with coordinates X,Y similar to a Vertical Sine function, I want to fill the area between left edge and the curve generated using variable color with colormap on matplot, changes in color whith X value as the image (From Blue to Red). I've tried and get this result where start point and final point are conected by a line. I need to fill the left area.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
#Data
y=np.arange(0,10,0.01)
x=np.sin(y)*y+2
#Set Array
xx=np.asarray(x)
yy=np.asarray(y)
path = Path(np.array([xx,yy]).transpose())
patch = PathPatch(path, facecolor='none')
plt.gca().add_patch(patch)
im = plt.imshow(xx.reshape(yy.size,1), cmap=plt.cm.coolwarm,interpolation="nearest",
origin='left',extent=[-5,10,0,10],aspect="auto", clip_path=patch, clip_on=True)
im.set_clip_path(patch)
You could add two additional points lying on the y-axis to create the desired shape:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
y = np.linspace(0, 10, 200)
x = np.sin(y) * y + 2
path = Path(np.array([np.append(x, [-5, -5]), np.append(y, [y[-1], y[0]])]).T)
patch = PathPatch(path, facecolor='none')
plt.gca().add_patch(patch)
im = plt.imshow(x.reshape(y.size, 1), cmap=plt.cm.coolwarm, interpolation="nearest",
origin='lower', extent=[-5, 10, 0, 10], aspect="auto", clip_path=patch, clip_on=True)
plt.show()
Im trying to crop rectangle image from screenshot, background for image must be white, Im ending up having black,How can I change that? I want to make histogtam of rgb for the final image and It seems plotting only vertical line on zero, Any kind of help is very important! here is my code:
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
image = cv2.imread(filename = "Screenshot from 2019-11-08 22-02-27.png")
mask = np.zeros(shape = image.shape, dtype = "uint8")
cv2.rectangle(img = mask,
pt1 = (0, 185), pt2 = (1900, 773),
color = (255, 255, 255),
thickness = -1)
maskedImg = cv2.bitwise_and(src1 = image, src2 = mask)
cv2.imwrite("processed.png", maskedImg)
plt.imshow(maskedImg)
plt.show()
plt.hist(maskedImg.ravel(),256,[0,256]); plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
image = cv2.imread(filename = "1.png")
mask = np.zeros(shape = image.shape, dtype = "uint8")
cv2.rectangle(img = mask,
pt1 = (0, 185), pt2 = (1900, 773),
color = (255, 255, 255),
thickness = -1)
maskedImg = cv2.bitwise_and(src1 = image, src2 = mask)
maskedImg[np.where((maskedImg==[0,0,0]).all(axis=2))] = [255,255,255]
cv2.imwrite("processed.png", maskedImg)
plt.imshow(maskedImg)
plt.show()
Convert the black pixel present in the image into white pixel
Original image
Crop Image
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([maskedImg],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
I would like to calculate the average grayscale profile of an image.
In my next code I have the evolution of the grayscale of all the pixels of the image, but how to make the average? To obtain a single curve, the average of all the others. Thank you
import imageio
import numpy as np
from matplotlib.pyplot import *
from matplotlib import pyplot as plt
img = imread("lion.jpg")
#
red = img[:,:,0]
green = img[:,:,1]
blue = img[:,:,2]
#print(np.mean(img)
line = red[:,:]
#here How to calculate the average grayscale profile?
figure(figsize=(8,4))
plot(line)
plt.show()
If I understand correctly, you want to have a profile of the greyscale image along both directions of the image.
import numpy as np
from matplotlib import pyplot as plt
img = plt.imread("https://i.stack.imgur.com/9qe6z.png")
# convert to grayscale
gray = img.mean(axis=2)
# or
#gray = np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
# profile along x -> mean along y
prof_x = gray.mean(axis=0)
# profile along y -> mean along x
prof_y = gray.mean(axis=1)
fig, (ax, ay) = plt.subplots(nrows=2, sharex=True, sharey=True)
ax.plot(prof_x, label="x profile")
ay.plot(prof_y, color="C1", label="y profile")
fig.legend()
plt.show()
I am trying to use SLIC to obtain superpixels and get semantic segmentation of an image.
img = cv2.imread(img_name)
segments = slic(image, n_segments = numSegments, sigma = 3,convert2lab=True,max_iter=25)
How do I get the box2d for each of the segments? and if there a hierarchical tree of the segments how do I fetch that?
I did not read the original paper, but according to documentation it does not return a hierarchy.
I assume that you mean bounding boxes, so used the skimage example of Regionprops to get bounding boxes for each superpixel returned by SLIC.
Result:
Code:
from skimage.segmentation import slic
from skimage.data import astronaut
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage.measure import label
from skimage.measure import regionprops
from skimage.color import label2rgb
img = astronaut()
segments = slic(img, n_segments=50, compactness = 100)
image_label_overlay = label2rgb(segments, image=img)
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(image_label_overlay)
for region in regionprops(segments):
minr, minc, maxr, maxc = region.bbox
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
plt.show()