I'm trying solve a challenging problem in C++ with the concepts I'm not familiar with.
I'm trying to apply a filter to a matrix. However like I said I'm quite new at this and after some investigation I've found this link where it shows applying a filter is basically a multiplication
However what confuses me that what if my filter is [0,1,0] and I have to apply it to a 5x5 matrix. How would I be able to do that?
GIMP Filtering with kernel
An alternative to first link
EDIT:Second link really confused me. I am pretty much right now trying to decide the "application" process. If I follow the idea of creating a 3x3 matrix with only diagonal [0,1,0] am i going to apply it like in the second link or do I have to apply it to every single cell in matrix. Or if its really going to be a 1-D filter should I,again, apply it to every single cell or leave out the edges and corners?
That's a convolution kernel.
The idea is that you replace each pixel with a weighted average of it and its neighbors, where the weight are given by your convolution kernel. The process is explained nicely e.g. here.
I find strange that you have a 1-D convolution kernel (i.e. that would be suitable for a one-dimensional image), when usually for image processing 2-D convolution kernels (which take pixels also from the rows above/below) are used, but it could be that your algorithm needs to work only with pixel from the current row.
I think the thing that's being overlooked is that the multiplication is repeated for every element of the input array using subsets of the input data.
The GIMP example showed how to filter a 5x5 image using a 3x3 filter for a single pixel:
. . . . . . . . . .
. - - - . . . . . . . . .
. - # - . x . . . -> . . # . .
. - - - . . . . . . . . .
. . . . . . . . . .
I've labelled one input pixel with a # and its neighbors with -. You use the smaller matrix:
- - - . . .
- # - x . . . = 3x3 array
- - - . . .
Sum up the numbers in the resultant 3x3 array, and store that value into the new image, in place of the # pixel.
To take this to your example, when filtering a 5x5 image using a 3x1 filter:
. . . . . . . . . .
. . . . . . . . . .
. - # - . x . . . -> . . # . .
. . . . . . . . . .
. . . . . . . . . .
You'll use a smaller subset of the input array, to match your kernel;
- # - x . . . = 1x3 array
Then, again, sum the numbers in the resultant array, and store that value into the new image in place of the # pixel.
It's confusing what you are looking for in an answer. If we make the assumption that your filter is stored in a std::vector<double> called filter and that your image is really 2D and has type std::vector< std::vector<double> > called image, then we can do the following to apply the 1-D filter [-1,0,1]:
std::vector< std::vector<double> > new_image;
std::vector<double> filter;
filter.push_back(-1.0); filter.push_back(0.0); filter.push_back(1.0);
for(int i = 0; i < image.size(); i++){
for(int j = 0; j < image.at(i).size(); j++){
new_image.at(i).push_back( filter.at(0)*image.at(i).at(j-1)
+ filter.at(1)*image.at(i).at(j)
+ filter.at(2)*image.at(i).at(j+1) );
}
}
If you want to have a 2-dimensional filter like this one for example
[0 1 0]
[1 0 1]
[0 1 0]
then we assume it is stored as a vector of vectors as well, and basically do the same.
std::vector< std::vector<double> > new_image;
for(int i = 0; i < image.size(); i++){
for(int j = 0; j < image.at(i).size(); j++){
top_filter_term = filter.at(0).at(0)*image.at(i-1).at(j-1)
+ filter.at(0).at(1)*image.at(i-1).at(j)
+ filter.at(0).at(2)*image.at(i-1).at(j+1);
mid_filter_term = filter.at(1).at(0)*image.at(i).at(j-1)
+ filter.at(1).at(1)*image.at(i).at(j)
+ filter.at(1).at(2)*image.at(i).at(j+1);
bot_filter_term = filter.at(2).at(0)*image.at(i+1).at(j-1)
+ filter.at(2).at(1)*image.at(i+1).at(j)
+ filter.at(2).at(2)*image.at(i+1).at(j+1);
new_image.at(i).push_back(top_filter_term + mid_filter_term + bot_filter_term);
}
}
Please note -- I'm not making any effort to do bounds checking for the filter arrays, you really you should only apply this away from the edges of the image, or add code to apply whatever kinds of boundary conditions you want for your filter. I'm also not making any claims about this being optimized. For most purposes, using vectors is a good way to go because they are dynamically resizable and provide enough built-in support to do a lot of useful image manipulations. But for really large-scale processing, you'll want to optimize things like filter operations.
As for your question about filtering a 3D array, there are a couple of things to consider. One, make sure that you really do want to filter the whole array. For many image processing tasks, it is better and more efficient to split all of the color channels into their own 2D arrays, do your processing, and then put them back together. If you do want a true 3D filter, then be sure that your filter actually is 3D, that is, it will be a vector of vectors of vectors. Then you'll use the exact same logic as above, but you'll have an additional layer of terms for the parts of the filter applied to each color channel, or "slice", of the image.
I think you are talking about color filter. Technically a 5X5 image is actually a 5X5X3 (A), where the '3' corresponds to 3 basic colors (RGB). Now, create a matrix of 3X3 with diagonal [0,1,0] (T).
Now multiply the two matrices (AXT) to get the new 5X5X3 image matrix.
Related
I am familiar with numpy.transpose command that it is used to swap axes. But I am not familiar with mirror images that what they are and how numpy.transpose command is used to generate mirror image. The following link says that when we swap last two axis we get mirror images. So what is meant by mirror images here. I will be really thankful if someone please explain this with some picture
`a= np.arange(2*2*4).reshape(2,2,4)
b= np.transpose(a,(1,0,2))`
please look https://imgur.com/gallery/v6z7ah0
https://www.reddit.com/r/learnpython/comments/734lcl/complicated_numpy_transpose_question/?st=jij0av7a&sh=754dfd45
In [54]: a= np.arange(2*3*4).reshape(3,2,4)
# | | |
# axes 0 1 2
# new shape by moving the axes
In [54]: b= np.transpose(a,(1,0,2))
In [55]: a.shape
Out[55]: (3, 2, 4)
# first two axes are swapped
In [56]: b.shape
Out[56]: (2, 3, 4)
By default, np.transpose() reverses the shape. But, when passing an argument to np.transpose() the array is reshaped to the requested shape if possible.
Explanation:
In the above example, np.transpose(a, (1, 0, 2)) means that in the returned array b, the zeroth and first axes would be swapped.
Specifically, the tuple that's passed to np.transpose() is the order in which we want our resultant array to have the shape.
Plotting the image before (left) and after transposing (right):
I want to create a small test data set with some specific values:
x
-
1
3
4
5
7
I can do this the hard way:
. set obs 5
. generate x = .
. replace x = 1 in 1
. replace x = 3 in 2
. replace x = 4 in 3
. replace x = 5 in 4
. replace x = 7 in 5
I can also use the data editor, but I'd like to create a .do file which can recreate this data set.
So how do I set the values of a variable from a list of numbers?
This can be done using a (to my mind) poorly documented feature of input:
clear
input x
1
3
4
5
7
end
I say poorly documented because the title of the input help page is
[D] Input -- Enter data from keyboard
which is clearly only a subset of what this command can do.
Here is another way
clear
mat x = (1,3,4,5,7)
set obs `=colsof(x)'
generate x = x[1, _n]
and another
clear
mata : x = (1,3,4,5,7)'
getmata x=x
I am working on a project and I wanted to animate some of my results. For my project there is lots of computation done but there is one parameter that I would like to vary.
I have made up some mock code to illustrate my question:
import matplotlib.pyplot as plt
import numpy as np
alpha = np.linspace(1, 10, 50)
x = np.linspace(0, 10, 100)
y = x * x
for i in range(len(alpha)):
plt.plot(x, alpha[i] * y)
plt.title("Alpha = " + str(alpha[i]))
plt.xlim(0, 10)
plt.ylim(1, 100)
plt.savefig("./animation_test/" + str(i) + "_Alpha=" + str(alpha[i]) + ".png")
plt.close()
This leaves me with a my images in a folder I made called animation_test. Now I was just going to run something in my bash terminal like
$convert -delay 50 * test.gif
to make a simple little animated gif but the ordering in my terminal is a little funny
0_Alpha=1.0.png
10_Alpha=2.83673469388.png
11_Alpha=3.02040816327.png
.
.
.
19_Alpha=4.48979591837.png
1_Alpha=1.18367346939.png
20_Alpha=4.67346938776.png
21_Alpha=4.85714285714.png
.
.
.
Now in my Finder they are listed in the correct order. Is there a better way to label these files or even a better way to do the animation as a whole? The final product doesn't have to be a .gif, just something I can play.
You have two solutions:
use human sorting
prepend zeros to your numbers in order to have a fixed number of digits.
Example, if you have labels like:
1-file.ext
2-file.ext
...
99-file.ext
you want to have something like:
01-file.ext
02-file.ext
...
99-file.ext
This is more of an algorithmic/math problem but I'm hoping to implement a solution in C++.
Suppose I have a matrix like so where the dots represent integers:
W X Y Z
A . . . .
B . . . .
C . . . .
D . . . .
How would I yield the minimum result if I had to pick one number from each column such that there is at most one number from each row?
For instance, I could choose AW BX CY DZ or AZ BX CY DW but NOT AW BW CZ DZ
The brute force approach would seem to take n! calculations. Is there a quicker way? Eventually I would like to add numbers in matrices of size ~60.
Also, all numbers range from 0 to 256.
And if you'd rather not code it yourself, you could always use someone else' hard-work and kind publication. This one in Haskell, solves a 60x60 random matrix in less than two tenths of a second on my old laptop. What a great algorithm!
import Data.Algorithm.Munkres
import Data.Array.Unboxed
import Data.List (transpose)
solve n matrix =
hungarianMethodInt (listArray ((1,1),(n,n)) $ concat $ transpose matrix)
I am trying to implement affine transformation on two images.
First i find the matching pairs in both of the images. One of them is zoomed image and the other is a reference image. The pairs returned me co-efficients as :
|1 0 | | x | | 1 |
A = | | X = | | B = | |
|0 0 | | y | | 221 |
The equation formed is X' = AX + B;
x_co_efficients[2] = (((x_new_Cordinate[2]-x_new_Cordinate[0])*(xCordinate[1]- xCordinate[0])) - ((x_new_Cordinate[1]-x_new_Cordinate[0])*(xCordinate[2] - xCordinate[0])))/
(((xCordinate[1]-xCordinate[0])*(yCordinate[2]-yCordinate[0])) - ((xCordinate[2]-xCordinate[0])*(yCordinate[1]-yCordinate[0])));
x_co_efficients[1] = ((x_new_Cordinate[1]-x_new_Cordinate[0]) - (yCordinate[1]-yCordinate[0])*(x_co_efficients[2]))/(xCordinate[1]-xCordinate[0]);
x_co_efficients[0] = x_new_Cordinate[0] - (((x_co_efficients[1])*(xCordinate[0])) + ((x_co_efficients[2])*(yCordinate[0])));
y_co_efficients[2] = (((y_new_Cordinate[2]-y_new_Cordinate[0])*(xCordinate[1]- xCordinate[0])) - ((y_new_Cordinate[1]-y_new_Cordinate[0])*(xCordinate[2] - xCordinate[0])))/
(((xCordinate[1]-xCordinate[0])*(yCordinate[2]-yCordinate[0])) - ((xCordinate[2]-xCordinate[0])*(yCordinate[1]-yCordinate[0])));
y_co_efficients[1] = ((y_new_Cordinate[1]-y_new_Cordinate[0]) - (yCordinate[1]-yCordinate[0])*(y_co_efficients[2]))/(xCordinate[1]-xCordinate[0]);
y_co_efficients[0] = y_new_Cordinate[0] - (((y_co_efficients[1])*(xCordinate[0])) + ((y_co_efficients[2])*(yCordinate[0])));
These are the equations i am used to finned the co-efficients from using the matching pairs. The equations are working fine for same images, for zooming image it is giving me those co-efficients. Now the problem is i have a 24 bit binary image, i want to implement affine transformation on that image with respect to reference. Now when i try to find the new co-ordinates of that image and change its current value to that co-ordinate I get a very much distorted image. which is should not get otherwise if the transformation is right.
Can Some one please have a look at the equations and also explain a little bit how to implement these equations on the second image.
My code is in C++. Thank you.
My reference image is above.. and my comparison image is
The result i am getting is a distorted image with lines only.
Edit 1
I have now changed the solving method to matrices. Now i am getting the right output but the image i am getting after registration is like this..
Also i have to applied limit of 0 to 320*240 in the new co-ordinates to get the pixel value. Now my result is somewhat like this.
EDIT 2
I have changed the code and m getting this result without any black pixels. I am getting a little tilting.. have removed zoom effect in the given image though.
Your transformation matrix A is problematic. It destroys the y coordinate value and assigns 221 to all y coordinates
You can make the element at (2,2) in A just 1 and problem should be solved.