导航:首页 > 车辆百科 > opencv车辆轮廓

opencv车辆轮廓

发布时间:2021-10-14 22:35:25

1、c++ opencv轮廓检测

opencv3/C++轮廓的提取与筛选,轮廓提取
findContours发现轮廓
1 findcontours(
2 InputoutputArray binImg,/输入8bit图像,0值酸素值不变,非0的酸素看成1;(变为二值图象)
3outputArrayofArrays contours,/新出转到的轮对象4 outputArray,hierachy//图像的拓扑结构5int mode,/轮家返回的模式YRETR TREE等)
6int method,//发现方法(CHAIN APPROX SIMPLE等)
7Point offset=Point0/轮廓像素的位移(默认没有位移(0,0))
8)

2、请教基于opencv的轮廓提取问题

先灰度化->二值化,弄成二值图,你就会提取了

给你个例子
C/C++ code

#include <stdio.h>

#include "cv.h"

#include "cxcore.h"

#include "highgui.h"

#include <iostream>

using namespace std;

#pragma comment(lib,"cv.lib")

#pragma comment(lib,"cxcore.lib")

#pragma comment(lib,"highgui.lib")

struct Position

{

int x,y;

};

double per[256];// 保存灰度概率

IplImage *FindCountours(IplImage* src,IplImage *pContourImg);

int ImageStretchByHistogram(IplImage *src,IplImage *dst);

IplImage* Hist_Equalization(IplImage *srcimg);

void proBorder(IplImage *src); // 边界的处理

void GetBackImage(IplImage* src,IplImage* src_back);

void Threshold(IplImage *src);

int GetThreshold(double *const prob);

void Getprobability(IplImage *src);

double Eccentricity(IplImage *src);

void main()

{

//IplImage * src = cvLoadImage("C:\\image19\\A634.jpg",-1);//灰度图的方式载入

IplImage * src = cvLoadImage("C:\\image19\\A857.jpg",-1);

IplImage * dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);

IplImage *src_back = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,src->nChannels);

GetBackImage(src,src_back);

dst = FindCountours(src_back,dst);

cvNamedWindow("test",CV_WINDOW_AUTOSIZE);

cvShowImage("test",dst);

cvWaitKey(0);

cvReleaseImage(&src);

cvReleaseImage(&dst);

}

void GetBackImage(IplImage* src,IplImage* src_back)

{

//cvCvtColor(src,src,CV_RGB2GRAY);//灰度化

IplImage *tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);

// 创建结构元素

IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);

//用该结构对源图象进行数学形态学的开操作后,估计背景亮度

cvErode(src,tmp,element,9);

//使用任意结构元素腐蚀图像

cvDilate(tmp,src_back, element,9);

//使用任意结构元素膨胀图像

}

IplImage *FindCountours(IplImage* src,IplImage *pContourImg)

{

CvMemStorage *storage = cvCreateMemStorage(0); //提取轮廓需要的储存容量为默认KB

CvSeq * pcontour = 0; //提取轮廓的序列指针

IplImage *temp = cvCreateImage(cvGetSize(src),src->depth,1);

//cvSmooth(src,temp,CV_GAUSSIAN,3,1,0);

cvSmooth(src,src,CV_GAUSSIAN,3,1,0);//平滑处理

cvCvtColor(src,temp,CV_RGB2GRAY);//灰度化

Getprobability(temp);

printf("最好的阈值:%d\n",GetThreshold(per));

//Threshold(temp);

proBorder(temp);

cvThreshold(temp,temp,GetThreshold(per),255,CV_THRESH_BINARY_INV);

int contoursNum = 0; // 轮廓数量

//int mode = CV_RETR_LIST;

int mode = CV_RETR_EXTERNAL;// 提取最外层轮廓

contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),mode,CV_CHAIN_APPROX_NONE);

// contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));

//二值图, 得到轮廓存储,轮廓指针序列,header_size,提取模式,逼近方法

CvScalar externalColor;// 保存颜色值

CvScalar holeColor;

//————–画轮廓—————-//

for (; pcontour != 0; pcontour=pcontour -> h_next)

{

//holeColor=CV_RGB(rand()&255,rand()&255,rand()&255);

//externalColor=CV_RGB(rand()&255,rand()&255,rand()&255);

CvRect r = ((CvContour *)pcontour)->rect;

if(r.height * r.width < 800)

{

holeColor=CV_RGB(0,0,0);

externalColor=CV_RGB(0,0,0);

cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);

}

else

{

//取得轮廓面积

double contArea = fabs(cvContourArea(pcontour,CV_WHOLE_SEQ));

//取得轮廓长度

double contLenth = cvArcLength(pcontour,CV_WHOLE_SEQ,-1);

// 圆形度

double contcircularity = contLenth * contLenth / contArea;

double pxl =Eccentricity(temp);

cout<<"面积为:"<<contArea<<endl;

cout<<"周长为:"<<contLenth<<endl;

cout<<"圆形度为:"<<contcircularity<<endl;

holeColor=CV_RGB(255,255,255);

externalColor=CV_RGB(255,255,255);

cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);

}

}

//IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);

//cvDilate(pContourImg,pContourImg, element,9);

return pContourImg;

}

double Eccentricity(IplImage *src)//偏心率

{

Position pos[4];

int width = src->width;

int height = src->height;

int i,j;

for(i = 0; i < height; i++)

{

for(j = 0; j < width; j++)

{

int pixel = (int)cvGet2D(src,i,j).val[0];

if(pixel != 0)

{

pos[0].x = j;

pos[0].y = i;//

goto s;

}

}

}

s:

for(i = height – 1; i >= 0; i–)

{

for(j = 0; j < width ; j++)

{

int pixel = (int)cvGet2D(src,i,j).val[0];

if(pixel != 0)

{

pos[1].x = j;

pos[1].y = i;//

goto w;

}

}

}

w:

for(i = 0 ; i < width ; i++)

{

for(j = 0;j < height; j++)

{

int pixel = (int)cvGet2D(src,j,i).val[0];

if(pixel != 0)

{

pos[2].x = j;//

pos[2].y = i;

goto e;

}

}

}

e:

for(i = width – 1; i >= 0; i–)

{

for(j = 0 ; j < height ; j++)

{

int pixel = (int)cvGet2D(src,j,i).val[0];

if(pixel != 0)

{

pos[3].x = j;//

pos[3].y = i;

goto f;

}

}

}

f:

int l_dis = abs(pos[0].y – pos[1].y);

int s_dis = abs(pos[2].x – pos[3].x);

int tmp_dis;

if(l_dis > s_dis)

{

printf("偏心率:%f\n",l_dis*1.0/s_dis);

}

else

{

tmp_dis = l_dis;

l_dis = s_dis;

s_dis = tmp_dis;

printf("偏心率:%f\n",l_dis*1.0/s_dis);

}

return 0;

}

void Getprobability(IplImage *src)

{

memset(per,0,sizeof(per));

int width = src->width;

int height = src->height;

for(int i = 0; i < height; i++) {

for(int j = 0; j < width; j++) {

per[(int)cvGet2D(src,i,j).val[0]]++;

}

}

int PixlNum = width * height;

for(i = 0; i < 256; i++)

per[i] = per[i] / PixlNum;

}

int GetThreshold(double *const prob)

{

int threshold = 0;

double maxf = 0;

for (int crrctThrshld = 1; crrctThrshld < 256 – 1; ++crrctThrshld) {

double W0 = 0, W1 = 0, U0 = 0, U1 = 0;

int i = 0;

for (i = 0; i <= crrctThrshld; ++i) {

U0 += i * prob[i];

W0 += prob[i];

}

for (; i < 256; ++i) {

U1 += i * prob[i];

W1 += prob[i];

}

if (W1 == 0 || W1 == 0)

continue;

U0 /= W0;

U1 /= W1;

double D0 = 0, D1= 0;

for (i = 0; i <= crrctThrshld; ++i)

D0 += pow((i – U0) * prob[i], 2.0);

for (; i < 256; ++i)

D1 += pow((i – U1) * prob[i], 2.0);

D0 /= W0;

D1 /= W1;

double Dw = pow(D0, 2.0) * W0 + pow(D1, 2.0) * W1;

double Db = W0 * W1 * pow((U1 – U0), 2.0);

double f = Db / (Db + Dw);

if (maxf < f) {

maxf = f;

threshold = crrctThrshld;

}

}

return threshold;

}

void proBorder(IplImage *src) // 边界的处理

{

int i,j;

int height = src->height;

int width = src->width;

int N = 100;

for(i = 0; i < N * width; i += width) // i表示向下走左上角

{

for(j = 0; j < N ; j++)

{

int index = i + j;

src->imageData[index] = (char)255;

}

}

int NN = 150;

int sw = width * (height – NN);// 左下角 三角形

int t = 1;

for(i = sw; i < sw + NN * width; i += width,t++)

{

for(j = 0; j < t; j++)

{

int index = i + j;

src->imageData[index] = (char)255;

}

}

int se = (height – NN – 1) * width; // 右下角

t = 0;

for(i = se; i < width * height ; i += width,t++)

{

for(j = 0; j < t; j++)

{

int index = i + j – t;

src->imageData[index] = (char)255;

}

}

int ne = width – NN; // 右上角 三角形剪切

t = 0;

for(i = ne; i < NN * width; i +=width,t++)

{

for(j = 0; j < NN – t; j++)

{

int index = i + j + t;

src->imageData[index] = (char)255;

}

}

}

void Threshold(IplImage *src)

{

int width = src->width;

int height = src->height;

float minpixel = cvGet2D(src,0,0).val[0];

float maxpixel = cvGet2D(src,0,0).val[0];

CvScalar s;

for(int i = 0; i < height; i++){

for(int j = 0; j < width; j++){

s = cvGet2D(src,i,j);

if(s.val[0] > maxpixel)

maxpixel = s.val[0];

if(s.val[0] < minpixel)

minpixel = s.val[0];

}

}

float firstgrey = (maxpixel + minpixel) / 2;

printf("%f\n",firstgrey);

float lastgrey;

float sum1 = 0,sum2 = 0;

int num1 = 0,num2 = 0;

int result = 0;

3、opencv 填充大致轮廓

这人形轮廓没有统一到一个轮廓下呀,opencv只能对单个轮廓进行填充,函数为cvDrawContours
( img, c, cvScalar(0,255,0,0),cvScalar(255,0,0,0), -1,2, 8, cvPoint(0, 0) );

4、在opencv下 如何将边缘检测后得到的车辆轮廓进行填充

?

5、请问,用opencv进行边缘检测,求轮廓后,怎么求轮廓间的最小距离(如下图)呢?请求详细的解答。谢谢

首先找到各点的质心,然后要是轮廓不多可以直接用简单的搜索来找就好

6、怎么用opencv在输入的原图上面已经寻找出来的轮廓

二值化,然后用countour那个函数就可以得到物体的轮廓。

7、opencv 怎样提取运动物体的轮廓?

你可以在提取的轮廓中进行识别,一般来说,车得轮廓比较大

8、opencv实现图像轮廓提取并矢量化

整个项目的结构图:

编写DetectFaceDemo.java,代码如下:

[java] view
plaincopyprint?

package com.njupt.zhb.test;

import org.opencv.core.Core;

import org.opencv.core.Mat;

import org.opencv.core.MatOfRect;

import org.opencv.core.Point;

import org.opencv.core.Rect;

import org.opencv.core.Scalar;

import org.opencv.highgui.Highgui;

import org.opencv.objdetect.CascadeClassifier;

//

// Detects faces in an image, draws boxes around them, and writes the results

// to "faceDetection.png".

//

public class DetectFaceDemo {

public void run() {

System.out.println("\nRunning DetectFaceDemo");

System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath());

// Create a face detector from the cascade file in the resources

// directory.

//CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("lbpcascade_frontalface.xml").getPath());

//Mat image = Highgui.imread(getClass().getResource("lena.png").getPath());

//注意:源程序的路径会多打印一个‘/’,因此总是出现如下错误

/*

* Detected 0 faces Writing faceDetection.png libpng warning: Image

* width is zero in IHDR libpng warning: Image height is zero in IHDR

* libpng error: Invalid IHDR data

*/

//因此,我们将第一个字符去掉

String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1);

CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath);

Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1));

// Detect faces in the image.

// MatOfRect is a special container class for Rect.

MatOfRect faceDetections = new MatOfRect();

faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

// Draw a bounding box around each face.

for (Rect rect : faceDetections.toArray()) {

Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));

}

// Save the visualized detection.

String filename = "faceDetection.png";

System.out.println(String.format("Writing %s", filename));

Highgui.imwrite(filename, image);

}

}
package com.njupt.zhb.test;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;

//
// Detects faces in an image, draws boxes around them, and writes the results
// to "faceDetection.png".
//
public class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
System.out.println(getClass().getResource("lbpcascade_frontalface.xml").getPath());
// Create a face detector from the cascade file in the resources
// directory.
//CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("lbpcascade_frontalface.xml").getPath());
//Mat image = Highgui.imread(getClass().getResource("lena.png").getPath());
//注意:源程序的路径会多打印一个‘/’,因此总是出现如下错误
/*
* Detected 0 faces Writing faceDetection.png libpng warning: Image
* width is zero in IHDR libpng warning: Image height is zero in IHDR
* libpng error: Invalid IHDR data
*/
//因此,我们将第一个字符去掉
String xmlfilePath=getClass().getResource("lbpcascade_frontalface.xml").getPath().substring(1);
CascadeClassifier faceDetector = new CascadeClassifier(xmlfilePath);
Mat image = Highgui.imread(getClass().getResource("we.jpg").getPath().substring(1));
// Detect faces in the image.
// MatOfRect is a special container class for Rect.
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

// Draw a bounding box around each face.
for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}

// Save the visualized detection.
String filename = "faceDetection.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}
}

3.编写测试类:

[java] view
plaincopyprint?

package com.njupt.zhb.test;

public class TestMain {

public static void main(String[] args) {

System.out.println("Hello, OpenCV");

// Load the native library.

System.loadLibrary("opencv_java246");

new DetectFaceDemo().run();

}

}

//运行结果:

//Hello, OpenCV

//

//Running DetectFaceDemo

///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml

//Detected 8 faces

//Writing faceDetection.png
package com.njupt.zhb.test;
public class TestMain {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
// Load the native library.
System.loadLibrary("opencv_java246");
new DetectFaceDemo().run();
}
}
//运行结果:
//Hello, OpenCV
//
//Running DetectFaceDemo
///E:/eclipse_Jee/workspace/JavaOpenCV246/bin/com/njupt/zhb/test/lbpcascade_frontalface.xml
//Detected 8 faces
//Writing faceDetection.png

9、如何利用OPENCV的matchShapes进行轮廓匹配

如何利用OPENCV的matchShapes进行轮廓匹配?主要步骤1.读取一幅图片,并且对其进行二值化。2.对其进行形态学处理,减少孔洞等次要特征,保留其主要特征。3.进行边缘提取。4.进行形状轮廓匹配,得到其匹配值,从而判断是否是同一个形状。
下面是演示代码:
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat k=imread("E:/TestGit/8.jpg",0);
Mat f;
Mat k1=imread("E:/TestGit/9.jpg",0);
Mat f1;
threshold(k,f,50,255,THRESH_BINARY);//对图像进行二值化
threshold(k1,f1,50,255,THRESH_BINARY);
Mat closerect=getStructuringElement(MORPH_RECT,Size(3,3)); //进行结构算子生成
morphologyEx(f,f,MORPH_OPEN,closerect);
morphologyEx(f1,f1,MORPH_OPEN,closerect);//进行形态学开运算
Mat dst = Mat::zeros(k.rows, k.cols, CV_8UC3);
Mat dst1 = Mat::zeros(k1.rows, k1.cols, CV_8UC3);
vector<vector<Point>> w,w1;
vector<Vec4i> hierarchy,hierarchy1 ;
findContours(f,w,hierarchy,RETR_CCOMP,CHAIN_APPROX_SIMPLE);//提取轮廓元素


与opencv车辆轮廓相关的内容