How to cut a circular part from an image?
Here is another easier way to do with SVG:
body {
background:pink;
}
<svg width="200" height="200">
<defs>
<mask id="hole">
<circle r="100" cx="100" cy="100" fill="white"/>
<circle r="50" cx="180" cy="180" fill="black"/>
</mask>
<pattern id="img" patternUnits="userSpaceOnUse" width="200" height="200">
<image xlink:href="https://picsum.photos/200/200?image=1069" x="0" y="0" width="200" height="200" />
</pattern>
</defs>
<!-- create a rect, fill it with the image and apply the above mask -->
<rect fill="url(#img)" width="100%" height="100%" mask="url(#hole)" />
</svg>
What's the most simple way to crop a circle thumbnail from an image?
first: HoughCircles
is used to detect circles on image, not to crop it.
You can't have circle image. Image is always rectangle but some of pixels can be transparent (alpha channel in RGBA
) and programs will not display them.
So you can first crop image to have square and later add alpha channel with information which pixels should be visible. And here you can use mask with white circle on black background. At the end you have to save it as png
or tiff
because jpg
can't keep alpha channel.
I use module PIL
/pillow
for this.
I crop square region in center of image but you can use different coordinates for this.
Next I create grayscale image with the same size and black background and draw white circle/ellipse.
Finally I add this image as alpha channel to cropped image and save it as png
.
from PIL import Image, ImageDraw
filename = 'dog.jpg'
# load image
img = Image.open(filename)
# crop image
width, height = img.size
x = (width - height)//2
img_cropped = img.crop((x, 0, x+height, height))
# create grayscale image with white circle (255) on black background (0)
mask = Image.new('L', img_cropped.size)
mask_draw = ImageDraw.Draw(mask)
width, height = img_cropped.size
mask_draw.ellipse((0, 0, width, height), fill=255)
#mask.show()
# add mask as alpha channel
img_cropped.putalpha(mask)
# save as png which keeps alpha channel
img_cropped.save('dog_circle.png')
img_cropped.show()
Result
BTW:
In mask you can use values from 0 to 255 and different pixels may have different transparency - some of them can be half-transparent to make smooth border.
If you want to use it in HTML on own page then you don't have to create circle image because web browser can round corners of image and display it as circle. You have to use CSS for this.
EDIT: Example with more circles on mask.
from PIL import Image, ImageDraw
filename = 'dog.jpg'
# load image
img = Image.open(filename)
# crop image
width, height = img.size
x = (width - height)//2
img_cropped = img.crop((x, 0, x+height, height))
# create grayscale image with white circle (255) on black background (0)
mask = Image.new('L', img_cropped.size)
mask_draw = ImageDraw.Draw(mask)
width, height = img_cropped.size
mask_draw.ellipse((50, 50, width-50, height-50), fill=255)
mask_draw.ellipse((0, 0, 250, 250), fill=255)
mask_draw.ellipse((width-250, 0, width, 250), fill=255)
# add mask as alpha channel
img_cropped.putalpha(mask)
# save as png which keeps alpha channel
img_cropped.save('dog_2.png')
img_cropped.show()
cropping an image in a circular way, using python
Here's one way to do it:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image, ImageDraw
# Open the input image as numpy array, convert to RGB
img=Image.open("dog.jpg").convert("RGB")
npImage=np.array(img)
h,w=img.size
# Create same size alpha layer with circle
alpha = Image.new('L', img.size,0)
draw = ImageDraw.Draw(alpha)
draw.pieslice([0,0,h,w],0,360,fill=255)
# Convert alpha Image to numpy array
npAlpha=np.array(alpha)
# Add alpha layer to RGB
npImage=np.dstack((npImage,npAlpha))
# Save with alpha
Image.fromarray(npImage).save('result.png')
CSS Circular Cropping of Rectangle Image
The approach is wrong, you need to apply the border-radius
to the container div
instead of the actual image.
This would work:
.image-cropper {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
border-radius: 50%;
}
img {
display: inline;
margin: 0 auto;
height: 100%;
width: auto;
}
<div class="image-cropper">
<img src="https://via.placeholder.com/150" class="rounded" />
</div>
cut out a specific part of an image with opencv in python
Here is one way in Python/OpenCV.
- Read the image
- Read the mask (separately created one time from your other image)
- Convert the mask to gray and threshold it to binary, invert it and make it 3 channels
- Get the center of the circle from your own code. (I have just measured it manually)
- Set the expected x,y offsets of the bottom of the region of text from the center of the circle
- Compute the expected top left corner of the mask from the center of the circle, the offsets and the height of the mask image
- Put the mask into black image the size of the input at that location
- Apply the new mask to the image to make the rest of the image black
- Crop out the region of interest from the top left corner and the size of the original mask
- OPTIONALLY, crop the original image
- Save the results
Input image:
Prepared mask image:
import cv2
import numpy as np
# read image
img = cv2.imread('die.jpg')
ht, wd, cc = img.shape
# read mask as grayscale
mask = cv2.imread('die_mask.png', cv2.IMREAD_GRAYSCALE)
# threshold mask and invert
mask = cv2.threshold(mask,0,255,cv2.THRESH_BINARY)[1]
mask = 255 - mask
hh, ww = mask.shape
# make mask 3 channel
mask = cv2.merge([mask,mask,mask])
# set circle center
cx = 62
cy = 336
# offsets from circle center to bottom of region
dx = -20
dy = -27
# compute top left corner of mask using size of mask and center and offsets
left = cx + dx
top = cy + dy - hh
# put mask into black background image
mask2 = np.zeros_like(img)
mask2[top:top+hh, left:left+ww] = mask
# apply mask to image
img_masked = cv2.bitwise_and(img, mask2)
# crop region
img_masked_cropped = img_masked[top:top+hh, left:left+ww]
# ALTERNATE just crop input
img_cropped = img[top:top+hh, left:left+ww]
cv2.imshow('image', img)
cv2.imshow('mask', mask)
cv2.imshow('mask2', mask2)
cv2.imshow('masked image', img_masked)
cv2.imshow('masked cropped image', img_masked_cropped)
cv2.imshow('cropped image', img_cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save results
cv2.imwrite('die_mask_inserted.jpg', mask2)
cv2.imwrite('die_masked_image.jpg', img_masked)
cv2.imwrite('die_masked_cropped.jpg', img_masked_cropped)
cv2.imwrite('die_cropped.jpg', img_cropped)
Mask inserted in black image:
Masked image:
Crop of masked image:
(Optional) Crop of input image:
Cropping circle from image using opencv python
1. Create a mask:
height,width = img.shape
mask = np.zeros((height,width), np.uint8)
2. Draw the circles on that mask (set thickness to -1 to fill the circle):
circle_img = cv2.circle(mask,(i[0],i[1]),i[2],(255,255,255),thickness=-1)
3. Copy that image using that mask:
masked_data = cv2.bitwise_and(img1, img1, mask=circle_img)
4. Apply Threshold
_,thresh = cv2.threshold(mask,1,255,cv2.THRESH_BINARY)
5. Find Contour
contours = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
x,y,w,h = cv2.boundingRect(contours[0])
6. Crop masked_data
crop = masked_data[y:y+h,x:x+w]
Adding this to your code
import cv2
import numpy as np
img1 = cv2.imread('amol.jpg')
img = cv2.imread('amol.jpg',0)
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
# Create mask
height,width = img.shape
mask = np.zeros((height,width), np.uint8)
edges = cv2.Canny(thresh, 100, 200)
#cv2.imshow('detected ',gray)
cimg=cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 10000, param1 = 50, param2 = 30, minRadius = 0, maxRadius = 0)
for i in circles[0,:]:
i[2]=i[2]+4
# Draw on mask
cv2.circle(mask,(i[0],i[1]),i[2],(255,255,255),thickness=-1)
# Copy that image using that mask
masked_data = cv2.bitwise_and(img1, img1, mask=mask)
# Apply Threshold
_,thresh = cv2.threshold(mask,1,255,cv2.THRESH_BINARY)
# Find Contour
contours = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
x,y,w,h = cv2.boundingRect(contours[0])
# Crop masked_data
crop = masked_data[y:y+h,x:x+w]
#Code to close Window
cv2.imshow('detected Edge',img1)
cv2.imshow('Cropped Eye',crop)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result using your image:
Most efficient way to crop image to circle (in R)?
You can improve the performance of your circ
function if you do a vectorised subset-assign operation on your array (instead of looping) using the the fact that (x-xc)^2 +(y-yc)^2 > r^2
for points outside a circle.
To do this, replace the 2nd part of your function with
# Second part of the function traces circle by...
x = rep(1:xmax, ymax)
y = rep(1:ymax, each=xmax)
r2 = r^2
ma[,,4][which(( (x-xc)^2 + (y-yc)^2 ) > r2)] <- 0
return(ma)
Related Topics
HTML - How to Do a Confirmation Popup to a Submit Button and Then Send the Request
Table Headers Position:Sticky and Border Issue
Open a Direct File on the Hard Drive from Firefox (File:///)
How to Move Placeholder to Top on Focus and While Typing
Space Between Buttons with Bootstrap Class
Triangle Bottom CSS with Background
Making All Images Appear with the Same Height in Bootstrap
How to Make <Legend> Text Wrap
3 Column Layout (Fixed, Fluid, Fixed) with Minimum Width
How to Remove the Top Margin in a Web Page
How to Include All CSS Kept in a Directory
How to Cut a Circular Part from an Image
How to Add a Margin Between Bootstrap Columns Without Wrapping
Set Child Width Relative to Its Parents Height in Pure CSS
Highlighting the Current Page in a List of Links Using CSS/Html
Responsive 2-Column CSS Layout Including Sidebar with Fixed Width