Dziękuję wszystkim za odpowiedź na to pytanie. Znalazłem mój błąd. Opiszę to krótko poniżej. Mam nadzieję, że pomoże to innym stawić czoła temu problemowi.
1) Wykonałem polecenia C i C++ na obrazie ROI. Wygląda na to, że sposób w jaki OpenCV "C" i "C++" traktuje ROI jest inny.
2) W "C" ROI jest traktowane jako zupełnie inny obraz. W związku z tym, gdy wykonuje się takie funkcje, jak cvSmooth, cvDilate itp., W których należy podać graniczne metody ekstrapolacji pikseli, interfejs API "C" nie odwołuje się do oryginalnego obrazu dla piksli poza lewym/prawym/górnym/na dole większości pikseli.W rzeczywistości interpoluje wartości pikseli zgodnie ze wspomnianą metodą.
3) Ale w "C++", stwierdziłem, że zawsze odnosi się do oryginalnego obrazu dla pikseli poza lewym/prawym/górnym/na dole większości pikseli. Dlatego wspomniana metoda ekstrapolacji pikseli obramowania nie ma wpływu na wynik, jeśli na oryginalnym obrazie wokół wskaźnika ROI znajdują się piksele.
Myślę, że stosuje się metodę ekstrapolacji pikseli zamówienia do oryginalnego obrazu zamiast ROI, w przeciwieństwie do API "C". Nie wiem, czy to błąd; Nie do końca przeczytałem dokumentację API OpenCV 2.4.2 C++. (Proszę mnie poprawić, jeśli się mylę)
Aby odebrać moje poparcie, jakie pisał obrazów wejściowych/wyjściowych poniżej:
wyjście do 'C' i C++ API:
INPUT:
input http://i48.tinypic.com/35jm9n5.png < --- wejście
OpenCV 'C' API:
IplImage *src = cvLoadImage("input.png", 0);
cvSetImageROI(src, cvRect(33,19,250,110));
cvSaveImage("before_gauss.png", src);
cvSmooth(src, src, CV_GAUSSIAN);
cvSaveImage("after_gauss.png", src);
IplConvKernel *element = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_RECT);
cvCanny(src, src, 140, 40);
cvSaveImage("after_canny.png", src);
cvDilate(src, src, element, 5);
cvSaveImage("dilate.png", src);
wyjściowych:
before_gauss http://i45.tinypic.com/345lybm.png < - before_gauss
after_gauss http://i45.tinypic.com/2rg1jm0.png < --- after_gauss
after_canny http://i46.tinypic.com/2ymhyqw.png < --- after_canny
dilate http://i48.tinypic.com/5u4ec1.png < --- rozszerzają
OpenCV 'C++' API:
cv::Mat src = cv::imread("input.png", 0);
cv::Mat src_ROI = src(cv::Rect(33,19,250,110));
cv::imwrite("before_gauss.png", src_ROI);
cv::GaussianBlur(src_ROI, src_ROI, cv::Size(3,3),0);
cv::imwrite("after_gauss.png", src_ROI);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(1,1));
cv::Canny(src_ROI, src_ROI, 140, 40);
cv::imwrite("after_canny.png", src_ROI);
cv::dilate(src_ROI, src_ROI, element, cv::Point(1,1), 5);
cv::imwrite("dilate.png", src_ROI);
WYJŚCIE:
before_gauss http://i45.tinypic.com/345lybm.png < - before_gauss
after_gauss http://i50.tinypic.com/28gxzrb.png
^^^^^ after_gauss (Uwaga: Granice nie są bardziej całkowicie czarne, są szarawe)
after_canny http://i45.tinypic.com/2la7ecp.png
^^^^^ after_canny
dilate http://i50.tinypic.com/jhqxbm.png
^^^^^ Jednokładność
ROZWIĄZANIE:
Stwórz osobną kopię ROI i używać go do dalszej analizy;
src_ROI.copyTo(new_src_ROI);
Użyj new_src_ROI do dalszej analizy. Jeśli ktoś ma lepsze rozwiązanie, opublikuj poniżej:
Czy możesz dołączyć oryginalny obraz? –
@ HåvardGeithus: Input: http://i47.tinypic.com/9kthzm.png; Obraz wejściowy jest sprytnym wyjściem krawędzi, jak pokazano. –