Julia-Lang: Square an image with a fixed background colour - julia

I have a series of images of different sizes.
x x x x
x x x x
x x x x
I would like to convert these to be square with a set fill colour in order to maintain aspect ratio.
x x x x
x x x x
x x x x
0 0 0 0
Is there any way to do this in Juila, preferably using the Images.jl package.

Assuming that you want to always up-broadcast the number of rows to square your image, the following function will get you what you need.
using Images, Colors
function square_up(image; value=RGB(0.,0.,0.))
A = data(image)
nrows, ncols = size(A)
fill_in_mat = fill(value, (ncols-nrows, ncols))
new_A = vcat(A, fill_in_mat)
new_image = copyproperties(image, new_A)
return new_image
end
Using a test image as an example:
using TestImages
img = testimage("mandrill")
# Cut the bottom half out of the image
A = data(img)
println(size(A))
B = A[1:floor(size(A, 1)/2.),:]
B_image = copyproperties(img, B)
# Apply the function to get new image filled with `value`
# The default is to fill with RGB(0,0,0)
out_image = square_up(B_image)
# Check that its square
println(size(out_image, 1) == size(out_image, 2))
To set the fill color, just mess with the value parameter.

Related

I have generated this data and I would like to plot it R

The data I have generated is as follows:
set.seed(100)
n = 100
c1_prob = 0.8
X = matrix(0, nrow = n, ncol = 2)
y = matrix(0,nrow=n,ncol=1)
for (i in 1:n){
if(runif(1) < c1_prob){
X[i,] = mvrnorm(1,mu=c(2,2),Sigma=matrix(c(1,0,0,1),2,2))
y[i] = 1;
} else {
X[i,] = mvrnorm(1,mu=c(-2,-2),Sigma=matrix(c(1,0,0,1),2,2))
y[i] = 0;
}
}
I want to plot X and then color in the points using the class labels of 1 or 0 from y. I tried to created a dataframe merging X and y and then plotting the first two columns, and then coloring based on the third column (originally y).
df = data.frame(cbind(X,y))
plot(df$X1, df$X2, col = df$X3)
This is not working however, and I was wondering if there is another way to do this. Specifically, is there a way to plot the data that does not require me to merge the two matrices into a dataframe. Thanks
try ggplots this is the general format from. If you wanna make a data frame and title them then instead of x,y just type in the titles of your columns
library(ggplot2)
your_data %>% ggplot(aes(X,Y, color = Y ))+geom_point()

How can I extract certain color with its position from a jpeg?

By library of 'JPEG', we can extract RGB matrix from a jpeg file. If I know the certain color in #RRGGBB format, how can I get the positions of the color points?
library(jpeg)
IMGMX <- readJPEG("sample.jpg") %>% melt %>% dcast(Var1+Var2~Var3, value.var = "value")
Re-scale data to [0, 255]
IMGMX[, 3:5] <- 255 * IMGMX[, 3:5]
Convert #RRGGBB to R, G, B coordinates
clr <- '#652d90'
r <- col2rgb(clr)[1]
g <- col2rgb(clr)[2]
b <- col2rgb(clr)[3]
Print matches
IMGMX[IMGMX$`1` == r & IMGMX$`2` == g & IMGMX$`3` == b, 1:2]
This will give you a dataframe comprised of 2 columns (width and height) and of n rows, corresponding to the n pixels in the original image that have the color 'clr'.

How to avoid gaps due to missing values in matplot in R?

I have a function that uses matplot to plot some data. Data structure is like this:
test = data.frame(x = 1:10, a = 1:10, b = 11:20)
matplot(test[,-1])
matlines(test[,1], test[,-1])
So far so good. However, if there are missing values in the data set, then there are gaps in the resulting plot, and I would like to avoid those by connecting the edges of the gaps.
test$a[3:4] = NA
test$b[7] = NA
matplot(test[,-1])
matlines(test[,1], test[,-1])
In the real situation this is inside a function, the dimension of the matrix is bigger and the number of rows, columns and the position of the non-overlapping missing values may change between different calls, so I'd like to find a solution that could handle this in a flexible way. I also need to use matlines
I was thinking maybe filling in the gaps with intrapolated data, but maybe there is a better solution.
I came across this exact situation today, but I didn't want to interpolate values - I just wanted the lines to "span the gaps", so to speak. I came up with a solution that, in my opinion, is more elegant than interpolating, so I thought I'd post it even though the question is rather old.
The problem causing the gaps is that there are NAs between consecutive values. So my solution is to 'shift' the column values so that there are no NA gaps. For example, a column consisting of c(1,2,NA,NA,5) would become c(1,2,5,NA,NA). I do this with a function called shift_vec_na() in an apply() loop. The x values also need to be adjusted, so we can make the x values into a matrix using the same principle, but using the columns of the y matrix to determine which values to shift.
Here's the code for the functions:
# x -> vector
# bool -> boolean vector; must be same length as x. The values of x where bool
# is TRUE will be 'shifted' to the front of the vector, and the back of the
# vector will be all NA (i.e. the number of NAs in the resulting vector is
# sum(!bool))
# returns the 'shifted' vector (will be the same length as x)
shift_vec_na <- function(x, bool){
n <- sum(bool)
if(n < length(x)){
x[1:n] <- x[bool]
x[(n + 1):length(x)] <- NA
}
return(x)
}
# x -> vector
# y -> matrix, where nrow(y) == length(x)
# returns a list of two elements ('x' and 'y') that contain the 'adjusted'
# values that can be used with 'matplot()'
adj_data_matplot <- function(x, y){
y2 <- apply(y, 2, function(col_i){
return(shift_vec_na(col_i, !is.na(col_i)))
})
x2 <- apply(y, 2, function(col_i){
return(shift_vec_na(x, !is.na(col_i)))
})
return(list(x = x2, y = y2))
}
Then, using the sample data:
test <- data.frame(x = 1:10, a = 1:10, b = 11:20)
test$a[3:4] <- NA
test$b[7] <- NA
lst <- adj_data_matplot(test[,1], test[,-1])
matplot(lst$x, lst$y, type = "b")
You could use the na.interpolation function from the imputeTS package:
test = data.frame(x = 1:10, a = 1:10, b = 11:20)
test$a[3:4] = NA
test$b[7] = NA
matplot(test[,-1])
matlines(test[,1], test[,-1])
library('imputeTS')
test <- na.interpolation(test, option = "linear")
matplot(test[,-1])
matlines(test[,1], test[,-1])
Had also the same issue today. In my context I was not permitted to interpolate. I am providing here a minimal, but sufficiently general working example of what I did. I hope it helps someone:
mymatplot <- function(data, main=NULL, xlab=NULL, ylab=NULL,...){
#graphical set up of the window
plot.new()
plot.window(xlim=c(1,ncol(data)), ylim=range(data, na.rm=TRUE))
mtext(text = xlab,side = 1, line = 3)
mtext(text = ylab,side = 2, line = 3)
mtext(text = main,side = 3, line = 0)
axis(1L)
axis(2L)
#plot the data
for(i in 1:nrow(data)){
nin.na <- !is.na(data[i,])
lines(x=which(nin.na), y=data[i,nin.na], col = i,...)
}
}
The core 'trick' is in x=which(nin.na). It aligns the data points of the line consistently with the indices of the x axis.
The lines
plot.new()
plot.window(xlim=c(1,ncol(data)), ylim=range(data, na.rm=TRUE))
mtext(text = xlab,side = 1, line = 3)
mtext(text = ylab,side = 2, line = 3)
mtext(text = main,side = 3, line = 0)
axis(1L)
axis(2L)`
draw the graphical part of the window.
range(data, na.rm=TRUE) adapts the plot to a proper size being able to include all data points.
mtext(...) is used to label the axes and provides the main title. The axes themselves are drawn by the axis(...) command.
The following for-loop plots the data.
The function head of mymatplot provides the ... argument for an optional passage of typical plot parameters as lty, lwt, cex etc. via . Those will be passed on to the lines.
At last word on the choice of colors - they are up to your flavor.

How convert spectral image elements to RGB in R language?

I'm planning to convert multispectral images to rgb based images- (RGB values of visible spectrum)
Basically, I'm reading png spectral image by "readPNG" function in R.
So, I have 2 dimensions 512X512 matrix. then according to the link above I write function that return values for R,G,B.
Now, my question is how I can apply this RGB to the my image to convert to rgb?
Some part of my code:
img <-readPNG("sample_img.png") # 512 X 512 Matrix
# after calculate R,G,B
r = 1
g = 0.892
b = 0
el1 <- img * r
el2 <- img * g
el3 <- img * b
col <- as.matrix(el1, el2, el3)
plot (1:512 , type="n" )
rasterImage(col, 1, 1, 512, 512)
I'm doing code like above , and still couldn't convert to get color image.
(more information about spectral: multispectral )
The rasterImage() function takes a 3D array, which you cannot create using as.matrix(). Instead, use abind() from the abind package.
library(abind)
col <- abind(el1, el2, el3, along=3)
plot (1:512 , type="n" )
rasterImage(col, 1, 1, 512, 512)
That should do it!

Merging two vectors at random in R

I have two vectors x and y. x is a larger vector compared to y. For example (x is set to all zeros here, but that need not be the case)
x = rep(0,20)
y = c(2,3,-1,-1)
What I want to accomplish is overlay some y's in x but at random. So in the above example, x would look like
0,0,2,3,-1,-1,0,0,0,0,2,3,-1,-1,...
Basically, I'll step through each value in x, pull a random number, and if that random number is less than some threshold, I want to overlay y for the next 4 places in x unless I've reached the end of x. Would any of the apply functions help? Thanks much in advance.
A simple way of doing it would be to choose points at random (the same length as x) from the two vectors combined:
sample(c(x, y), length(x), replace = TRUE)
If you want to introduce some probability into it, you could do something like:
p <- c(rep(2, each = length(x)), rep(1, each = length(y)))
sample(c(x, y), length(x), prob = p, replace = TRUE)
This is saying that an x point is twice as likely to be chosen over a y point (change the 2 and 1 in p accordingly for different probabilities).
Short answer: yes :-) . Write some function like
ranx <- runif(length(x)-length(y)+1)
# some loop or apply func...
if (ranx[j] < threshold) x[j:j+length(y)] <- y
# and make sure to stop the loop at length(y)-length(x)
Something like the following worked for me.
i = 1
while(i <= length(x)){
p.rand = runif(1,0,1)
if(p.rand < prob[i]){
p[i:(i+length(y))] = y
i = i+length(y)
}
i = i + 1
}
where prob[i] is some probability vector.

Resources