We would like to c开发者_如何学Correct for field curvature introduced by a lens in a digital camera. We plan to use a digital unsharp mask Instead of applying a Gaussian blur we would like to try a radial blur, so the sharpening has more impact toward the edges of the image.
What is simplest way to create a radial blur using OpenCV ?
The answer above is close but missing a few key elements that took me a bit to figure out. I've changed the maps so that they are correctly calculating the zoom and shrink and added/subtracted them from the x and y at each position (otherwise you will just end up remapping your image to a tiny square. Also I changed the /blur to *blur otherwise your maps will contain very large numbers and just not come out right (extremely large multiples of each position).
float center_x = width/2; //or whatever
float center_y = height/2;
float blur = 0.002; //blur radius per pixels from center. 2px blur at 1000px from center
int iterations = 5;
Mat growMapx, growMapy;
Mat shrinkMapx, shrinkMapy;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
growMapx[x,y] = x+((x - center_x)*blur);
growMapy[x,y] = y+((y - center_y)*blur);
shrinkMapx[x,y] = x-((x - center_x)*blur);
shrinkMapy[x,y] = y-((y - center_y)*blur);
}
}
Mat tmp1, tmp2;
for(int i = 0; i < iterations; i++) {
remap(src, tmp1, growMapx, growMapy, CV_INTER_LINEAR); // enlarge
remap(src, tmp2, shrinkMapx, shrinkMapy, CV_INTER_LINEAR); // shrink
addWeighted(tmp1, 0.5, tmp2, 0.5, 0, src); // blend back to src
}
Python code:
w, h = img.shape[:2]
center_x = w / 2
center_y = h / 2
blur = 0.01
iterations = 5
growMapx = np.tile(np.arange(h) + ((np.arange(h) - center_x)*blur), (w, 1)).astype(np.float32)
shrinkMapx = np.tile(np.arange(h) - ((np.arange(h) - center_x)*blur), (w, 1)).astype(np.float32)
growMapy = np.tile(np.arange(w) + ((np.arange(w) - center_y)*blur), (h, 1)).transpose().astype(np.float32)
shrinkMapy = np.tile(np.arange(w) - ((np.arange(w) - center_y)*blur), (h, 1)).transpose().astype(np.float32)
for i in range(iterations):
tmp1 = cv2.remap(img, growMapx, growMapy, cv2.INTER_LINEAR)
tmp2 = cv2.remap(img, shrinkMapx, shrinkMapy, cv2.INTER_LINEAR)
img = cv2.addWeighted(tmp1, 0.5, tmp2, 0.5, 0)
I am interested in something similar to the Photoshop radial motion blur. If this is also what you are looking for, I think the best solution might be an iterative resize
and blend (addWeighted
). Can also be accomplished with remap
. Pseudocode, more or less:
float center_x = width/2; //or whatever
float center_y = height/2;
float blur = 0.02; //blur radius per pixels from center. 2px blur at 100px from center
int iterations = 5;
Mat mapx, mapy;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
mapx[x,y] = (x - center_x)/blur;
mapy[x,y] = (y - center_y)/blur;
}
}
Mat tmp1, tmp2;
for(int i = 0; i < iterations; i++) {
remap(src, tmp1, mapx, mapy, CV_INTER_LINEAR); // enlarge
remap(src, tmp2, -mapx, -mapy, CV_INTER_LINEAR); // shrink
addWeighted(tmp1, 0.5, tmp2, 0.5, 0, src); // blend back to src
}
精彩评论