2013-08-30 103 views
1

我被卡住的從Python到C++的答案之一移植代碼,我希望有人可以幫助做到這一點,並澄清過程的一部分。OpenCV - 去除凸性缺陷(Python到C++)

我談論了答案 - https://stackoverflow.com/a/11366549

我在其中步驟重心正在排序(一個之前的最後一個)。有問題的代碼完成這項工作,但我不確定如何使用C++獲得相同的結果,而不會使代碼更長。

centroids = np.array(centroids,dtype = np.float32) 
c = centroids.reshape((100,2)) 
c2 = c[np.argsort(c[:,1])] 

b = np.vstack([c2[i*10:(i+1)*10][np.argsort(c2[i*10:(i+1)*10,0])] for i in xrange(10)]) 
bm = b.reshape((10,10,2)) 

我要實現這一點的方法是做如下:

  • 最初的重心陣列的方式已經排序(最高Y值點有索引0,最低的有99) ,所以我想反轉它,使數組從上到下排列。

  • 之後,它只是一個通過行(排序10排,10列由X軸)

我相信這是所有有許多工作要做排序的問題,但我不能找到一種優雅的方式編碼(不使用矢量,手動排序)。

我也不太理解最後一步,圖像被扭曲(使其很難移植),所以如果任何人都可以提供一些見解,這部分可能會做什麼,可能C++等效於此,我會很感激。

output = np.zeros((450,450,3),np.uint8) 
for i,j in enumerate(b): 
    ri = i/10 
    ci = i%10 
    if ci != 9 and ri!=9: 
     src = bm[ri:ri+2, ci:ci+2 , :].reshape((4,2)) 
     dst = np.array([ [ci*50,ri*50],[(ci+1)*50-1,ri*50],[ci*50,(ri+1)*50-1],[(ci+1)*50-1,(ri+1)*50-1] ], np.float32) 
     retval = cv2.getPerspectiveTransform(src,dst) 
     warp = cv2.warpPerspective(res2,retval,(450,450)) 
     output[ri*50:(ri+1)*50-1 , ci*50:(ci+1)*50-1] = warp[ri*50:(ri+1)*50-1 , ci*50:(ci+1)*50-1].copy() 

我只是學習OpenCV的都和C++的,我知道這可能是微不足道的,所以我希望有人能抽出一些時間,並提供一定程度基本答案。

編輯

根據要求,這裏的代碼。我已經處理了第一部分,仍然不確定這是否是正確的路。

#pragma mark Correcting the defects 
findContours(res, contours, RETR_LIST, CHAIN_APPROX_SIMPLE); 
vector<cv::Point> centroids; 
centroids.reserve(100); 

for (int i = 0; i < contours.size(); i++) { 
    vector<cv::Point> contour = contours.at(i); 
    Moments mom = moments(contour); 
    cv::Point center = cv::Point(int(mom.m10/mom.m00), int(mom.m01/mom.m00)); 
    centroids.push_back(center); 
} 

std::reverse(centroids.begin(), centroids.end()); 

struct { 
    bool operator()(const cv::Point p1, const cv::Point p2) { 
     return p1.x < p2.x; 
    } 
} pointXGreater; 

for (int i = 0; i < 10; i++) { 
    std::sort(centroids.begin() + i * 10, centroids.begin() + (i + 1) * 10, pointXGreater); 
} 

Mat b(centroids); 
Mat bm = b.reshape(10, 10); 

在用索引繪製圖像上的質心後,似乎它們是正確的。

現在我被困在最後一部分,試圖破譯Python代碼,並不知道它的功能。到目前爲止,我得到這個:

Mat output = Mat::zeros(450, 450, CV_8U); 

for (int i = 0; i < centroids.size(); i++) { 
    cv::Point j = centroids.at(i); 

    int ri = i/10; 
    int ci = i % 10; 

    if (ci != 9 && ri != 9) { 
     Mat src = ?? 
     Mat dst = ?? 
     Mat retval = getPerspectiveTransform(src, dst); 
     Mat warp; 
     warpPerspective(res2, warp, retval, (450, 450)); 
     Mat output = ?? 
    } 
} 

我會繼續努力,以它的意義,但一些幫助真的可以理解,因爲這種Python語法不是很友好,特別是如果你真的不知道正在做什麼。

+0

你爲什麼不張貼C++你已經嘗試了這個特定的部分? Stack Overflow不是代碼翻譯服務,但如果您遇到特定問題,我們很樂意爲您提供幫助。另外,如果你還沒有閱讀['std :: sort()'](http://en.cppreference.com/w/cpp/algorithm/sort),你可能想閱讀。 – Aurelius

+0

我沒有發佈,因爲我不想讓帖子更長(我認爲這已經很長了)。我非常清楚,這不是代碼翻譯服務,我也沒有想到它會是。我只是認爲這是一個非常具體的主題,有足夠經驗的人可以指引我走向正確的方向。如果明天仍然有用,我會用我嘗試過的代碼擴展我的帖子。 此外,我檢查了std :: sort out,並嘗試在我的一次嘗試中使用它,但正如我所說我是C++的新手,可能犯了一些錯誤。 – Ilija

回答

1

一會兒撞頭後,這是我想出了(似乎工作)

#pragma mark Correcting the defects 
findContours(res, contours, RETR_LIST, CHAIN_APPROX_SIMPLE); 
vector<cv::Point> centroids; 
centroids.reserve(100); 

for (int i = 0; i < contours.size(); i++) { 
    vector<cv::Point> contour = contours.at(i); 
    Moments mom = moments(contour); 
    cv::Point center = cv::Point(int(mom.m10/mom.m00), int(mom.m01/mom.m00)); 
    centroids.push_back(center); 
} 

std::reverse(centroids.begin(), centroids.end()); 

struct { 
    bool operator()(const cv::Point p1, const cv::Point p2) { 
     return p1.x < p2.x; 
    } 
} pointXGreater; 

for (int i = 0; i < 10; i++) { 
    std::sort(centroids.begin() + i * 10, centroids.begin() + (i + 1) * 10, pointXGreater); 
} 

Mat bm = Mat(centroids); 
bm = bm.reshape(2, 10); 

Mat output(450, 450, CV_8UC3, CV_RGB(1, 1, 1)); 

for (int i = 0; i < centroids.size(); i++) { 
    int ri = i/10; 
    int ci = i % 10; 

    if (ci != 9 && ri != 9) { 
     cv::Point2f src[4]; 
     src[0] = cv::Point2f(bm.at<cv::Point>(ri, ci).x, bm.at<cv::Point>(ri, ci).y); 
     src[1] = cv::Point2f(bm.at<cv::Point>(ri, ci + 1).x, bm.at<cv::Point>(ri, ci + 1).y); 
     src[2] = cv::Point2f(bm.at<cv::Point>(ri + 1, ci).x, bm.at<cv::Point>(ri + 1, ci).y); 
     src[3] = cv::Point2f(bm.at<cv::Point>(ri + 1, ci + 1).x, bm.at<cv::Point>(ri + 1, ci + 1).y); 

     cv::Point2f dst[4]; 
     dst[0] = cv::Point2f(ci * 50, ri * 50); 
     dst[1] = cv::Point2f((ci + 1) * 50 - 1, ri * 50); 
     dst[2] = cv::Point2f(ci * 50, (ri + 1) * 50 - 1); 
     dst[3] = cv::Point2f((ci + 1) * 50 - 1, (ri + 1) * 50 - 1); 

     Mat retval = getPerspectiveTransform(src, dst); 
     Mat warp; 
     warpPerspective(res2, warp, retval, cv::Size(450, 450)); 

     for (int j = ri * 50; j < (ri + 1) * 50 - 1; j++) { 
      for (int k = ci * 50; k < (ci + 1) * 50 - 1; k++) { 
       output.at<Vec3b>(j, k) = warp.at<Vec3b>(j, k); 
      } 
     } 
    } 
}