我想将第一张图片转换为第二张图片,我想也许是仿射转换。我的问题和疑问如下:
(1)。正如我上面提到的,我认为变换是仿射变换。因此,第一步是通过沿顺时针方向单击第一个图像中的三个角点(从鼠标回调函数返回坐标)找到三对对应点,并将其对应点设置为特定坐标(每个角点之间的距离已知) 。第二步是使用getAffineTransform()和warpAffine()方法来实现仿射变换。但是这种方法已经证明不够好(见第三张图),所以有什么想法可以改善结果吗?
我的代码如下所示:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/features2d/features2d.hpp"
#include <stdio.h>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
Mat org;
int n=0;
vector<Point> capturePoint;
void on_mouse(int event,int x,int y,int flags,void *ustc)
{
Point pt;
char coordinateName[16];
if (event == CV_EVENT_LBUTTONDOWN)
{
pt = Point(x,y);
cout<<x<<" "<<y<<endl;
capturePoint.push_back(pt);
n++;
circle(org,pt,2,Scalar(255,0,0,0),CV_FILLED,CV_AA,0);
sprintf(coordinateName,"(%d,%d)",x,y);
putText(org,coordinateName,pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255),1,8);
//imshow("org",org);
if(n>=4)
{
imshow("org",org);
cvDestroyAllWindows();
}
}
}
int main()
{
org = imread("1-3.jpg",1);
namedWindow("org",1);
setMouseCallback("org",on_mouse,0);// mouse callback;
imshow("org",org);
waitKey(0);
//cout<<capturePoint.size()<<endl;
//three pairs of corresponding points;
Point2f srcPoint[3];
Point2f dstPoint[3];
srcPoint[0]=capturePoint[0];//mouse click along clockwise direction;
srcPoint[1]=capturePoint[1];
srcPoint[2]=capturePoint[2];
//srcPoint[3]=capturePoint[3];
dstPoint[0]=Point(0,0);//distances between each corner point are known;
dstPoint[1]=Point(640,0);//width=320,height=220;
dstPoint[2]=Point(640,440);
//dstPoint[3]=Point(0,220);
Mat warpDst=Mat(org.rows, org.cols, org.type());
//Mat warpMat = findHomography( srcPoint, dstPoint, 0 );
Mat warpMat = getAffineTransform(srcPoint,dstPoint);
warpAffine(org,warpDst,warpMat,org.size());//affine transformation;
imshow("Warp",warpDst);
waitKey(0);
return 0;
}
(2)。我想在没有人工干预的情况下实现转换,即不需要手动选择点,因此我想在第一个图像中使用椭圆中心及其对应点来实现仿射变换。我的问题是,如果椭圆中心可用于实现仿射变换,如果可以,则如何检测椭圆中心。
(3)。我使用canny方法获得最大轮廓,并应用cornerHarris来检测最大轮廓的角点。我发现每个角落可能有一些彼此靠近的候选点。那么如何获得四个&#34;&#34;角点?
答案 0 :(得分:0)
我使用cv2(python绑定)玩你的图像。它仍然不完美,但您可以使用参数进一步改进。较小的k改善了角点检测。门槛也很重要。
import cv2
from pylab import *
fp = "qkwWV.jpg"
img = cv2.imread(fp)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# edge and corner detection using cornerHarris
blockSize = 16
ksize = 7
k = 0.005
corners = cv2.cornerHarris(gray, blockSize, ksize, k)
cv2.normalize( corners, corners, 0, 255, cv2.NORM_MINMAX, cv2.CV_32F, None)
# play with threshold until only 4 corners are left.
figure()
thrs = 173
imshow(corners>thrs, cmap=cm.gray)
# get the center coordinates of 4 groups using k-means
y,x = np.where(corners>thrs)
candidates = np.array(zip(x,y)).astype(np.float32)
term_crit = (cv2.TERM_CRITERIA_EPS, 30, 0.1)
flags = cv2.KMEANS_RANDOM_CENTERS
ret, labels, centers = cv2.kmeans(candidates, 4, term_crit, 10, flags)
# draw cross haris on the original image
centers = centers.astype(np.int)
L = 40
for _x, _y in centers:
cv2.line(img, (_x-L, _y), (_x+L, _y), (255,0,0), 3)
cv2.line(img, (_x, _y-L), (_x, _y+L), (255,0,0), 3)
figure()
imshow(img)
show()