相邻轮廓合并

OpenCV python 轮廓之间的距离(相似性)
处理图片:[cs1.jpg]

处理图片:[cs2.jpg]

处理图片:[hand.jpg]


import cv2


def get_contours(img):
    """获取连通域

    :param img: 输入图片
    :return: 最大连通域
    """
    # 灰度化, 二值化, 连通域分析
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    ret, img_bin = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

    img_contour, contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    return contours[0]


def main():

    # 1.导入图片
    img_cs1 = cv2.imread("cs1.jpg")
    img_cs2 = cv2.imread("cs2.jpg")
    img_hand = cv2.imread("hand.jpg")

    # 2.获取图片连通域
    cnt_cs1 = get_contours(img_cs1)
    cnt_cs2 = get_contours(img_cs2)
    cnt_hand = get_contours(img_hand)

    # 3.创建计算距离对象
    hausdorff_sd = cv2.createHausdorffDistanceExtractor()

    # 4.计算轮廓之间的距离
    d1 = hausdorff_sd.computeDistance(cnt_cs1, cnt_cs1)
    print("与自身的距离hausdorff\t d1=", d1)

    d2 = hausdorff_sd.computeDistance(cnt_cs1, cnt_cs2)
    print("与相似图片的距离hausdorff\t d2=", d2)

    d3 = hausdorff_sd.computeDistance(cnt_cs1, cnt_hand)
    print("与不同图片的距离hausdorff\t d3=", d3)

    # 5.显示图片
    cv2.imshow("img_cs1", img_cs1)
    cv2.imshow("img_cs2", img_cs2)
    cv2.imshow("img_hand", img_hand)

    cv2.waitKey()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

笨方法:

绘制轮廓与连通大凸包
#简单的想法是将每个凸包手动画线连接成一整个连通区域,然后重新寻找一个大凸包
hulls = []
lines = []
for cnt in contours:
    hull = cv2.convexHull(cnt)
    lines.append(tuple(hull[0][0]))

for j in range(len(lines)):
    if j + 1 < len(lines):
        cv2.line(img,lines[j], lines[j + 1],(255, 255, 255), 2)
cv2.imshow('fig_lines', img)

#在连线完的图片上重新寻找最外层轮廓
gray2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret2, binary2 = cv2.threshold(gray2, 235, 255, cv2.THRESH_BINARY)
contours2, heriachy2 = cv2.findContours(binary2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt2 in contours2:
    hull2 = cv2.convexHull(cnt2)
    hulls.append(hull2)

draw_hulls = cv2.drawContours(img, hulls, -1, (0, 0, 255), 2) #最后一个参数-1表示填充
cv2.imshow('fig_hull', draw_hulls)
————————————————
版权声明:本文为CSDN博主「一路悠扬」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_19765635/article/details/102552678
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
using namespace std;
using namespace cv;
Mat img,smallImg,gray,bw;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
int threshval=128;
Rect r;
Rect maxrect,brect;
int idx,n;
const static Scalar colors[15]={
    CV_RGB(  0,  0,128),
    CV_RGB(  0,128,  0),
    CV_RGB(  0,128,128),
    CV_RGB(128,  0,  0),
    CV_RGB(128,  0,128),
    CV_RGB(128,128,  0),
    CV_RGB(128,128,128),
    CV_RGB(160,160,160),
    CV_RGB(  0,  0,255),
    CV_RGB(  0,255,  0),
    CV_RGB(  0,255,255),
    CV_RGB(255,  0,  0),
    CV_RGB(255,  0,255),
    CV_RGB(255,255,  0),
    CV_RGB(255,255,255),
};
Scalar color;
void gamma_correct(Mat& img, Mat& dst, double gamma) {
    Mat    temp;
    CvMat tmp;
 
    img.convertTo(temp,    CV_32FC1, 1.0/255.0, 0.0);
    tmp=temp;
    cvPow(&tmp,    &tmp, gamma);
    temp.convertTo(dst , CV_8UC1 , 255.0    , 0.0);
}
int main() {
    cvNamedWindow("display",1);
    img=imread("image.jpg",1);
    r.x=img.cols/10;
    r.y=img.rows/3;
    r.width=img.cols*8/10;
    r.height=img.rows*2/3;
    smallImg=img(r);
    cvtColor(smallImg,gray,CV_BGR2GRAY);
//  medianBlur(gray,gray,5);
    equalizeHist(gray,gray);
    gamma_correct(gray,gray,4.0);
    imshow("display",gray);
    waitKey(0);
 
    bw=(gray>threshval);
    imshow("display",bw);
    waitKey(0);
 
    Mat    Structure0=getStructuringElement(MORPH_RECT,Size(3,3));
    erode(bw,bw,Structure0,Point(-1,-1));
    Mat    Structure1=getStructuringElement(MORPH_RECT,Size(6,6));
    dilate(bw,bw,Structure1, Point(-1,-1));
    imshow("display",bw);
    waitKey(0);
 
    findContours(bw,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
    if (!contours.empty()&&!hierarchy.empty()) {
        idx=0;
        n=0;
        vector<Point> approx;
        for (;idx>=0;idx=hierarchy[idx][0]) {
            color=colors[idx%15];
//          drawContours(smallImg,contours,idx,color,1,8,hierarchy);
            approxPolyDP(Mat(contours[idx]), approx, arcLength(Mat(contours[idx]), true)*0.005, true);//0.005为将毛边拉直的系数
            const Point* p = &approx[0];
            int m=(int)approx.size();
            polylines(smallImg, &p, &m, 1, true, color);
            circle(smallImg,Point(p[0].x,p[0].y),3,color);
            circle(smallImg,Point(p[1].x,p[1].y),2,color);
            for    (int i=2;i<m;i++) circle(smallImg,Point(p[i].x,p[i].y),1,color);
            n++;
            if (1==n) {
                maxrect=boundingRect(Mat(contours[idx]));
            } else {
                brect=boundingRect(Mat(contours[idx]));
                CvRect mr(maxrect),br(brect);
                maxrect=cvMaxRect(&mr,&br);
            }
        }
        circle(smallImg,Point(maxrect.x+maxrect.width/2,maxrect.y+maxrect.height/2),2,CV_RGB(255,0,0));
    }
    imshow("display",smallImg);
    waitKey(0);
    cvDestroyWindow("display");
    return 0;
}

另一个:

#include <iostream>
#include <OpenCV/cv.h>
#include <OPenCV/highgui.h>

using namespace cv;
using namespace std;

CvRect rect;
CvSeq* contours = 0;
CvMemStorage* storage = NULL;
CvCapture *cam;
IplImage *currentFrame, *currentFrame_grey, *differenceImg, *oldFrame_grey;

bool first = true;

int main(int argc, char* argv[])
{
   //Create a new movie capture object.
   cam = cvCaptureFromCAM(0);

   //create storage for contours
   storage = cvCreateMemStorage(0);

   //capture current frame from webcam
   currentFrame = cvQueryFrame(cam);

   //Size of the image.
   CvSize imgSize;
   imgSize.width = currentFrame->width;
   imgSize.height = currentFrame->height;

   //Images to use in the program.
   currentFrame_grey = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);                           

   while(1)
   {
          currentFrame = cvQueryFrame( cam );
          if( !currentFrame ) break;

          //Convert the image to grayscale.
          cvCvtColor(currentFrame,currentFrame_grey,CV_RGB2GRAY);

          if(first) //Capturing Background for the first time
          {
                 differenceImg = cvCloneImage(currentFrame_grey);
                 oldFrame_grey = cvCloneImage(currentFrame_grey);
                 cvConvertScale(currentFrame_grey, oldFrame_grey, 1.0, 0.0);
                 first = false;
                 continue;
          }

          //Minus the current frame from the moving average.
          cvAbsDiff(oldFrame_grey,currentFrame_grey,differenceImg);

          //bluring the differnece image
          cvSmooth(differenceImg, differenceImg, CV_BLUR);             

          //apply threshold to discard small unwanted movements
          cvThreshold(differenceImg, differenceImg, 25, 255, CV_THRESH_BINARY);

          //find contours
          cvFindContours( differenceImg, storage, &contours );

          //draw bounding box around each contour
          for(; contours!=0; contours = contours->h_next)
          {
                 rect = cvBoundingRect(contours, 0); //extract bounding box for current contour

                 //drawing rectangle
                 cvRectangle(currentFrame,                  
                              cvPoint(rect.x, rect.y),    
                              cvPoint(rect.x+rect.width, rect.y+rect.height),
                              cvScalar(0, 0, 255, 0),
                              2, 8, 0);                 
          }

          //display colour image with bounding box
          cvShowImage("Output Image", currentFrame);

          //display threshold image
          cvShowImage("Difference image", differenceImg);

          //New Background
          cvConvertScale(currentFrame_grey, oldFrame_grey, 1.0, 0.0);

          //clear memory and contours
          cvClearMemStorage( storage );
          contours = 0;

          //press Esc to exit
          char c = cvWaitKey(33);
          if( c == 27 ) break;

   }

   // Destroy the image & movies objects
   cvReleaseImage(&oldFrame_grey);
   cvReleaseImage(&differenceImg);
   cvReleaseImage(&currentFrame);
   cvReleaseImage(&currentFrame_grey);
   //cvReleaseCapture(&cam);

   return 0;

猜你喜欢

转载自blog.csdn.net/jacke121/article/details/115223325