टीएल; डीआर: एक आयताकार छवि को एक सर्कल में फसल करने का सबसे प्रभावी तरीका क्या है?छवि को सर्कल करने के लिए सबसे प्रभावी तरीका (आर में)?
स्पष्टीकरण/पृष्ठभूमि:
मैं कुछ कोड पर काम कर रहा हूँ आर में है कि डिफ़ॉल्ट rectanges बजाय हलकों/वर्गों के रूप में Spotify कलाकार छवियों को प्रदर्शित करेगा। मुझे कोई संकुल या आदेश नहीं मिला जो आर में विशेष रूप से एक सर्कल में छवियों को फसल करता है, इसलिए मैंने अपना स्वयं का फ़ंक्शन लिखा, circ
, जो 3-आयामी (या 4-आयामी) आरजीबी (ए) सरणी पढ़ता है और उन्हें फसल करता है हर अद्वितीय वाई के लिए एक्स मान निर्धारित करने के लिए the parametric equation of a circle का उपयोग करके सर्कल। यहाँ मेरी psuedocode है:
Given an RGB(A) array:
Find the center of the image, radius = min(x coord, y coord)
Pre-crop the image to a square of dimensions 2r x 2r
For every unique y value:
Determine the x coordinates on the circle
Make pixels outside of the circle transparent
Return the cropped image as an RGBA array
इस समारोह मेरे पिछले एक है, जो हर पिक्सेल की स्थिति की जाँच करता है, तो इसके अंदर या सर्कल के बाहर था देखने के लिए खत्म हो गया एक जबरदस्त सुधार है, लेकिन मैं अब भी लगता है जैसे कि यह तेज किया जा सकता है आगे बढ़ो
क्या कोई तरीका है कि मैं उन सभी के बजाय वाई-मानों का आधा हिस्सा देख सकता हूं, और सर्कल में दर्पण कर सकता हूं? क्या कोई वास्तविक क्रॉपिंग फ़ंक्शन है जिसका मैं उपयोग कर सकता हूं? किसी भी और सभी मदद की बहुत सराहना की है!
संपादित कुछ कॉपी-पेस्ट रन कोड (धन्यवाद @lukeA) जोड़ने के लिए:
मेरी मूल फसल विधि:
circ = function(a){
# First part of the function finds the radius of the circle and crops the image accordingly
xc = floor(dim(a[,,1])[2]/2) # X coordinate of the center
yc = floor(dim(a[,,1])[1]/2) # Y coordinate of the center
r = min(xc, yc) - 1 # Radius is the smaller of the two -1 to avoid reading nonexistent data
ma = array(data = c(a[,,1][(yc-r):(yc+r),(xc-r):(xc+r)], # Read in the cropped image
a[,,2][(yc-r):(yc+r),(xc-r):(xc+r)], # Of dimensions 2r x 2r, centered
a[,,3][(yc-r):(yc+r),(xc-r):(xc+r)], # Around (xc, yc)
rep(1,length(a[,,1][(yc-r):(yc+r),(xc-r):(xc+r)]))), # Add fourth alpha layer
dim = c(length((yc-r):(yc+r)),length((xc-r):(xc+r)),4))
if(yc > xc) yc = xc else if(xc > yc) xc = yc # Re-evaluate your center for the cropped image
xmax = dim(ma[,,1])[2]; ymax = dim(ma[,,1])[1] # Find maximum x and y values
# Second part of the function traces circle by the parametric eqn. and makes outside pixels transparent
for(y in 1:ymax){ # For every y in the cropped image
theta = asin((y - yc)/r) # y = yc + r * sin(theta) by parametric equation for a circle
x = xc + r * cos(theta) # Then we can find the exact x coordinate using the same formula
x = which.min(abs(1:xmax - x)) # Find which x in array is closest to exact coordinate
if(!x - xc == 0 && !xmax - x == 0){ # If you're not at the "corners" of the circle
ma[,,4][y,c(1:(xmax-x), (x+1):xmax)] = 0 # Make pixels on either side of the circle trans.
} else if(!xmax - x == 0) ma[,,4][y,] = 0 # This line makes tops/bottoms transparent
}
return(ma)
}
library(jpeg)
a = readJPEG("http://1.bp.blogspot.com/-KYvXCEvK9T4/Uyv8xyDQnTI/AAAAAAAAHFY/swaAHLS-ql0/s1600/pink-smiley-face-balls-laughing-HD-image-for-faacebook-sharing.jpg")
par(bg = "grey"); plot(1:2, type="n") # Color background to check transparency
rasterImage(circ(a),1,1,2,2)
संशोधित संस्करण (धन्यवाद @dww):
dwwcirc = function(a){
# First part of the function finds the radius of the circle and crops the image accordingly
xc = floor(dim(a[,,1])[2]/2) # X coordinate of the center
yc = floor(dim(a[,,1])[1]/2) # Y coordinate of the center
r = min(xc, yc) - 1 # Radius is the smaller of the two -1 to avoid reading nonexistent data
ma = array(data = c(a[,,1][(yc-r):(yc+r),(xc-r):(xc+r)], # Read in the cropped image
a[,,2][(yc-r):(yc+r),(xc-r):(xc+r)], # Of dimensions 2r x 2r, centered
a[,,3][(yc-r):(yc+r),(xc-r):(xc+r)], # Around (xc, yc)
rep(1,length(a[,,1][(yc-r):(yc+r),(xc-r):(xc+r)]))), # Add fourth alpha layer
dim = c(length((yc-r):(yc+r)),length((xc-r):(xc+r)),4))
if(yc > xc) yc = xc else if(xc > yc) xc = yc # Re-evaluate your center for the cropped image
xmax = dim(ma[,,1])[2]; ymax = dim(ma[,,1])[1] # Find maximum x and y values
x = rep(1:xmax, ymax) # Vector containing all x values
y = rep(1:ymax, each=xmax) # Value containing all y values
r2 = r^2
ma[,,4][which(((x-xc)^2 + (y-yc)^2) > r2)] = 0
return(ma)
}
library(jpeg)
a = readJPEG("http://1.bp.blogspot.com/-KYvXCEvK9T4/Uyv8xyDQnTI/AAAAAAAAHFY/swaAHLS-ql0/s1600/pink-smiley-face-balls-laughing-HD-image-for-faacebook-sharing.jpg")
par(bg = "grey"); plot(1:2, type="n") # Color background to check transparency
rasterImage(dwwcirc(a),1,1,2,2)
मैजिक और प्लॉट्रिक्स का उपयोग कर संस्करण (धन्यवाद @lukeA और @hrbrmstr):
library(plotrix)
jpeg(tf <- tempfile(fileext = "jpeg"), 1000, 1000)
par(mar = rep(0,4), yaxs="i", xaxs = "i")
plot(0, type = "n", ylim = c(0, 1), xlim = c(0,1), axes=F, xlab=NA, ylab=NA)
draw.circle(.5,.5,.5,col="black")
dev.off()
library(magick)
img = image_read("http://1.bp.blogspot.com/-KYvXCEvK9T4/Uyv8xyDQnTI/AAAAAAAAHFY/swaAHLS-ql0/s1600/pink-smiley-face-balls-laughing-HD-image-for-faacebook-sharing.jpg")
mask = image_read(tf)
radius = min(c(image_info(img)$width, image_info(img)$height))
mask = image_scale(mask, as.character(radius))
par(bg = "grey"); plot(1:2, type="n")
rasterImage(as.raster(image_composite(image = mask, composite_image = img, operator = "plus")),1,1,2,2)
के साथ अपने समारोह के 2 भाग की जगह आप इमेजर :: imsub क्रॉप कर सकते हैं, लेकिन यह केवल आयताकार तर्क लेता है। आप जो भी कर रहे हैं उसके साथ रहना होगा, लेकिन यह आपके ह्युरिस्टिक के एक कदम को काट देगा। – shayaa
क्या आपको इस तरह आर को हैक करने की कोशिश करने के बजाय वास्तविक छवि प्रसंस्करण उपकरण का उपयोग नहीं करना चाहिए? –
[मैं केवल टीएल पढ़ता हूं; डॉ] रास्टर मास्क बनाने के लिए ग्रिड ग्राफिक्स के साथ उदाहरण हैं – baptiste