灰度影象的一階和二階導數程式碼實現
阿新 • • 發佈:2019-01-02
#include <stdio.h> #include <iostream> #include <cv.h> #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include <opencv2/opencv.hpp> using namespace cv; using namespace std; void kcvShowImageStretchAbs(const char* winName, const IplImage* img) { IplImage* imgAbs = cvCloneImage(img); IplImage* img8u = cvCreateImage(cvGetSize(img), 8, img->nChannels); cvAbs(img, imgAbs); cvNormalize(imgAbs, img8u, 255, 0, CV_MINMAX); cvNamedWindow(winName); cvShowImage(winName, img8u); cvReleaseImage(&imgAbs); cvReleaseImage(&img8u); } int main() { IplImage* src = cvLoadImage("20170502110711-666_看圖王.jpg", 1); IplImage* srcGray = cvCreateImage(cvGetSize(src), 8, 1); IplImage* srcDx = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 1); IplImage* srcDy = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 1); IplImage* srcDxx = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 1); IplImage* srcDyy = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 1); IplImage* srcDxy = cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, 1); cvSetZero(srcDx); cvSetZero(srcDy); cvSet(srcDxx,cvScalarAll(255)); cvSet(srcDyy, cvScalarAll(255)); cvSet(srcDxy, cvScalarAll(255)); cvCvtColor(src,srcGray,CV_BGR2GRAY); uchar* sptr = (uchar*)srcGray->imageData; uchar* sptrNext = (uchar*)srcGray->imageData; uchar* sptrPrev = (uchar*)srcGray->imageData; int sstep = srcGray->widthStep/sizeof(char); int w = srcGray->width; int h = srcGray->height; short* xptr = (short*)srcDx->imageData; short* yptr = (short*)srcDy->imageData; int xstep = srcDx->widthStep/sizeof(short); int ystep = srcDy->widthStep /sizeof(short); short* xxptr = (short*)srcDxx->imageData; short* yyptr = (short*)srcDyy->imageData; short* xyptr = (short*)srcDxy->imageData; int xxstep = srcDxx->widthStep / sizeof(short); int yystep = srcDyy->widthStep / sizeof(short); int xystep = srcDxy->widthStep / sizeof(short); sptrNext += sstep; for (int i = 0; i < h - 1; i++, sptr += sstep, sptrNext += sstep, xptr += xstep, yptr += ystep) { for (int j = 0; j < w - 1;j++) { yptr[j] = sptrNext[j] - sptr[j]; xptr[j] = sptr[j + 1] - sptr[j]; } } //最後一行,複製上一行內容 short* xptrPrev = xptr - xstep; short* yptrPrev = yptr - ystep; for (int j = 0; j < w ; j++) { xptr[j] = xptrPrev[j]; yptr[j] = yptrPrev[j]; } //最後一列,複製前一列內容 xptr = (short*)srcDx->imageData; yptr = (short*)srcDy->imageData; for (int i = 0; i < h; i++, xptr += xstep, yptr += ystep) { xptr[w - 1] = xptr[w - 2]; yptr[w - 1] = yptr[w - 2]; } kcvShowImageStretchAbs("srcDx", srcDx); kcvShowImageStretchAbs("srcDy", srcDy); //指標歸位,二階導數求導 sptr = (uchar*)srcGray->imageData; sptrNext = (uchar*)srcGray->imageData; sptrPrev = (uchar*)srcGray->imageData; sptrNext += 2*sstep; sptr += sstep; yyptr += yystep; xxptr += xxstep; xyptr += xystep; for (int i = 1; i < h-1 ; i++, sptr += sstep, sptrNext += sstep, yyptr += yystep, xxptr += xxstep, xyptr += xystep) { for (int j = 1; j < w - 1; j++) { yyptr[j] = sptrNext[j] - 2 * sptr[j] + sptrPrev[j]; xxptr[j] = sptr[j + 1] - 2 * sptr[j] + sptr[j - 1]; xyptr[j] = sptrNext[j + 1] + sptr[j] - sptr[j + 1] - sptrNext[j]; } sptrPrev = sptr; } //四周邊界處理 xxptr = (short*)srcDxx->imageData; yyptr = (short*)srcDyy->imageData; xyptr = (short*)srcDxy->imageData; for (int i = 0; i < h; i++, xxptr += xxstep, yyptr += yystep,xyptr += xystep) { xxptr[0] = xxptr[1]; xxptr[w - 1] = xxptr[w - 2]; yyptr[0] = yyptr[1]; yyptr[w - 1] = yyptr[w - 2]; xyptr[0] = xyptr[1]; xyptr[w - 1] = xyptr[w - 2]; } xxptr = (short*)srcDxx->imageData; yyptr = (short*)srcDyy->imageData; xyptr = (short*)srcDxy->imageData; short* xxptrNext = xxptr + xxstep; short* yyptrNext = yyptr + yystep; short* xyptrNext = xyptr + xystep; for (int j = 0; j < w; j++) { xxptr[j] = xxptrNext[j]; yyptr[j] = yyptrNext[j]; xyptr[j] = xyptrNext[j]; } xxptr += (h - 1)*xxstep; yyptr += (h - 1)*yystep; xyptr += (h - 1)*xystep; short* xxptrPrev = xxptr - xxstep; short* yyptrPrev = yyptr - yystep; short* xyptrPrev = xyptr - xystep; for (int j = 0; j < w; j++) { xxptr[j] = xxptrPrev[j]; yyptr[j] = yyptrPrev[j]; xyptr[j] = xyptrPrev[j]; } kcvShowImageStretchAbs("srcDxx", srcDxx); kcvShowImageStretchAbs("srcDyy", srcDyy); kcvShowImageStretchAbs("srcDxy", srcDxy); cvReleaseImage(&src); cvReleaseImage(&srcGray); cvReleaseImage(&srcDx); cvReleaseImage(&srcDy); cvReleaseImage(&srcDxx); cvReleaseImage(&srcDyy); cvReleaseImage(&srcDxy); cvWaitKey(-1); return 0; }