Reputation: 61
I have the coordinates of the upper left corner of the bottom semicircle and I know how the length and width of the semicircle if it were to be enclosed in a rectangle. What I want to be able to do, is to translate the bottom semicircle up 4 pixels. So could somebody give some code to translate a section of an image knowing all the coordinates? Thanks.
Upvotes: 1
Views: 748
Reputation: 61
Thanks for the help @Rachel L, but I figured it out a while ago. Basically I created a separate image containing the semicircle on the bottom, and I used a method to get the top left corner of every semicircle on the bottom. Then I figured out the length and width of the semicircle and just moved all the black pixels in the box that I created up 5 units which aligned it.
I probably should have added that this was part of a bigger project where I needed to move all the semicircles on the bottom from this image so that they were all aligned meaning that I wouldn't know the coordinates of them.
method for extracting locations of semicircles
def extract(name1, name2):
img_rgb = cv2.imread(name1)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread(name2,0)
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
arr = []
for pt in zip(*loc[::-1]):
if "down" in name2:
pt = (pt[0], pt[1] + 1)
arr.append(pt)
return arr
code to move semicircle up
locFillSemiDown = extract('img' + str(num) + '.png', 'filledsemidown.png')
for loc in locSemiDown:
for y in range(loc[0], loc[0] + 11):
for x in range(loc[1], loc[1] + 6):
if(img.item(x,y,0) == 0 and img.item(x,y,1) == 0 and img.item(x,y,2) == 0):
img.itemset((x - 5, y,0),0)
img.itemset((x - 5, y,1),0)
img.itemset((x - 5, y,2),0)
img.itemset((x, y,0),0)
img.itemset((x, y,1),255)
img.itemset((x, y,2),255)
Upvotes: 1
Reputation: 327
For that particular image, you can get away with grabbing the rectangle plus 4-6 pixel rows, then put that ROI on the image the 4 pixels higher that you want.
This is in C++, but it should be similar enough you can translate it.
#include "stdafx.h"
#include <opencv/cxcore.h>
#include <opencv2\core\mat.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv/cxcore.h>
#include <opencv/cv.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;
using namespace std;
int main() {
//getting the image
Mat image = imread("C:/this/is/a/link/to/an/image.png");
//create new image that looks exactly like old image
Mat new_image = image.clone();
//showing the image
namedWindow("Image", CV_WINDOW_NORMAL| CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED);
imshow("Image", image);
waitKey(0);
//getting the roi coordinates
int x = 13, y = 8; //eyeballing the coordinates
int w = 26-x, h = 20-y; //more eyeballing the coordinates
//grabbing the roi
Rect roi = Rect(x, y, w, h);
Mat img_roi = image(roi);
//creating the new roi
Rect new_roi = Rect(x, y-4, w, h);
//copying the old roi onto the new image in the space of the new roi
img_roi.copyTo(new_image(new_roi));
//displaying the image
imshow("Image", new_image);
waitKey(0);
//saving the new image
imwrite("C:/this/is/a/link/to/a/newimage.png", new_image);
}
Results in this:
Now, this works because you've got more yellow that you can grab below the rectangle you're looking for.
If you trim it to exactly the rectangle you want to move, then it just overlays the roi on the old image, and you'll end up with part of your "moved" image where it was.
Like this:
Upvotes: 0