opencv小项目(鞋面roi提取)

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp> 
#include <opencv2/imgcodecs.hpp> 
#include<opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace std;



void fillHole(const Mat srcBw, Mat &dstBw);

int main(int argc, char** argv)
{
	Mat image = imread("C:/Users/think/Desktop/sole/定位孔/3.bmp");
	if (image.empty()) {
		cout << "could not find the image resource..." << std::endl;
		return -1;
	}
	resize(image,image,Size(500,300));
	Mat gray_image;
	cvtColor(image, gray_image, CV_BGR2GRAY);
	namedWindow("test image", CV_WINDOW_NORMAL);
	imshow("test image", gray_image);



	/*滤波处理*/
	//Mat dst, dst1;
	//blur(gray_image, dst, Size(3, 3), Point(-1, -1));
	//namedWindow("均值滤波");
	//imshow("均值滤波", dst);
	//GaussianBlur(gray_image, dst, Size(5, 5), 5, 5);
	//namedWindow("高斯滤波");
	//imshow("高斯滤波", dst);
	//medianBlur(gray_image, dst, 5);
	//namedWindow("中值滤波");
	//imshow("中值滤波", dst);
	//bilateralFilter(gray_image, dst, 5, 100, 3);
	//namedWindow("双边滤波");
	//imshow("双边滤波", dst);


	/*二值图像*/
	Mat result;
	threshold(gray_image, result, 130, 255, CV_THRESH_BINARY_INV);    //可以使用trackbar的方式去调阈值
	imshow("erzhi", result);
	/*填洞*/
	Mat fillhole;
	fillHole(result, fillhole);
	imshow("fillhole", fillhole);

	/*                     提取roi区域                   */
	/*提取鞋面二值图像*/
	int x = 0;
	int y = 0;
	int largest_contour_index = 0; 
	//Rect bounding_rect;
	int largest_area = 0;
	Mat ImageContours = Mat::zeros(fillhole.size(), CV_8UC1);
	Mat ImgContours = Mat::zeros(fillhole.size(), CV_8UC1);
	std::vector<cv::Rect> blue_rect;
	vector<vector<Point> > contours; // Vector for storing contours
	vector<Vec4i> hierarchy;
	findContours(fillhole, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE); // Find the contours in the image

	for (size_t i = 0; i< contours.size(); i++)  // iterate through each contour.
	{
		double area = contourArea(contours[i]);  //  Find the area of contour
		if (area > largest_area)
		{
			largest_area = area;
			largest_contour_index = i;		     //Store the index of largest contour
		}	
	}


	for (int j = 0; j < contours[largest_contour_index].size(); j++)
	{
		//获取轮廓上点的坐标
		Point P = Point(contours[largest_contour_index][j].x, contours[largest_contour_index][j].y);
		ImgContours.at<uchar>(P) = 255;
	}
	drawContours(ImageContours, contours, largest_contour_index, Scalar(255), -1, 8,noArray(),2147483647,Point(1,1));  //画出了面积最大的区域

	imshow("轮廓", ImageContours);
	//imshow("轮廓点集合", ImgContours);
	/* 对鞋面区域做roi提取*/

	/*1.提取重心*/

	Mat tmp(contours.at(largest_contour_index)); //这里只是画一个区域的重心,如果需要可以直接用for循环去遍历所有的区域来找所有区域的重心
	Moments moment = moments(tmp, false);
	if (moment.m00 != 0)//除数不能为0
	{
		 x = cvRound(moment.m10 / moment.m00);//计算重心横坐标
		 y = cvRound(moment.m01 / moment.m00);//计算重心纵坐标
	
	}

	circle(ImageContours, Point(x, y), 1, Scalar(0,0,255), 1, 8);
	//imshow("hua dian ", ImageContours);			//记得重新开画板去显示图像

	/*2.做仿射变换*/

	Mat suoxiao_img;

	suoxiao_img = getRotationMatrix2D(Point(x,y),0,0.95);
	warpAffine(ImageContours, suoxiao_img, suoxiao_img, ImageContours.size(), INTER_LINEAR);
	//imshow("suofang dian ", suoxiao_img);

	/*3.相减得到感兴趣的区域*/
	Mat roi_regin;
	roi_regin = ImageContours - suoxiao_img;
	imshow("roi region", roi_regin);

	/*4.还原原来的阈值图像*/
	Mat roi_image;
	bitwise_and(gray_image,roi_regin, roi_image);
	imshow("roi_image", roi_image);

	/*5.对原来的图像做阈值处理*/

	Mat yuzhi_image;
	//blur(yuzhi_image, yuzhi_image,Size(3,3));
	threshold(roi_image,yuzhi_image,22,253,THRESH_BINARY);
	//adaptiveThreshold(roi_image, yuzhi_image,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY_INV,3,3);
	namedWindow("yuzhi",0);
	imshow("yuzhi",yuzhi_image);

	/*6.形态学操作*/

	/*图像置反*/
	//bitwise_not(yuzhi_image, roi_image);
	//imshow("qufan", roi_image);

	///*腐蚀膨胀+开运算+闭运算*/
	  Mat erodeElement = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
	  Mat xingtai_image;
	dilate(fillhole,mat_image_dst, erodeElement); //膨胀
	 //erode(yuzhi_image, xingtai_image, erodeElement); //腐蚀

	 morphologyEx(yuzhi_image, xingtai_image, MORPH_OPEN, erodeElement, Point(-1, -1));//改变MORPH_OPEN可以变成闭运算
	 imshow("形态学处理", xingtai_image);


	/*边缘处理*/
	//Mat canny_contour;
	//Canny(roi, canny_contour, 50, 200, 3);//还有Sobel和Laplance,x相应使用要求可以具体的API
	//imshow("edge", canny_contour);



	waitKey(0);
	return 0;
	}



void fillHole(const Mat srcBw, Mat &dstBw)
{
	Size m_Size = srcBw.size();
	Mat Temp = Mat::zeros(m_Size.height + 2, m_Size.width + 2, srcBw.type());//延展图像
	srcBw.copyTo(Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));

	cv::floodFill(Temp, Point(0, 0), Scalar(255));

	Mat cutImg;//裁剪延展的图像
	Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);

	dstBw = srcBw | (~cutImg);
}

效果就是这样了

OpenCV项目 这是一个个人在使用OpenCV过程中写的一些小项目,以及一些非常有用的OpenCV代码,有些代码是对某论文中的部分实现。 注意:代码是在Xcode里写的,如果要在win下测试,遇到问题自己修改。 opencv-rootsift-py 用python和OpenCV写的一个rootsift实现,其中RootSIFT部分的代码参照Implementing RootSIFT in Python and OpenCV这篇文章所写,通过这个你可以了解Three things everyone should know to improve object retrieval这篇文章中RootSIFT是怎么实现的。 sift(asift)-match-with-ransac-cpp 用C++和OpenCV写的一个图像匹配实现,里面包含了采用1NN匹配可视化、1NN匹配后经RANSAC剔除错配点可视化、1NN/2NN<0.8匹配可视化、1NN/2NN<0.8经 RANSAC剔除错配点可视化四个过程,其中1NN/2NN<0.8匹配过程是Lowe的Raw feature match,具体可以阅读Lowe的Distinctive image features from scale-invariant keypoints这篇文章。这个对图像检索重排非常有用。另外里面还有用OpenCV写的ASIFT,这部分来源于OPENCV ASIFT C++ IMPLEMENTATION,ASIFT还可以到官网页面下载,ASIFT提取的关键点 比SIFT要多得多,速度非常慢,不推荐在对要求实时性的应用中使用。 更多详细的分析可以阅读博文SIFT(ASIFT) Matching with RANSAC。 有用链接 OpenCV3.0文档 // 测试sparse unsigned int centersNum = 10; vector descrNums; descrNums.push_back(8); descrNums.push_back(12); //unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5; 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5, 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; sp_mat Hist(descrNums.size(), centersNum); static long int count = 0; for (int i = 0; i < descrNums.size(); i++){ unsigned int* desrcElementsTmp = new unsigned int[descrNums[i]]; memcpy(desrcElementsTmp, T + count, descrNums[i] * sizeof(T[0])); //cout << desrcElementsTmp[0] << '\t' << desrcElementsTmp[1] << '\t' << desrcElementsTmp[2] << '\t' << desrcElementsTmp[3] << '\t' << desrcElementsTmp[4] << '\t' <<endl; //cout << desrcElementsTmp[5] << '\t' << desrcElementsTmp[6] << '\t' << desrcElementsTmp[7] << '\t' << desrcElementsTmp[8] << '\t' << desrcElementsTmp[9] << '\t' << desrcElementsTmp[10] << '\t' <<endl; //cout << endl; sp_mat X(1, centersNum); X.zeros(); for (int j = 0; j < descrNums[i]; j++){ X(0, desrcElementsTmp[j]-1) += 1; } X.print("X:"); X = X/norm(X, 2); Hist.row(i) = X; count = count + descrNums[i]; delete desrcElementsTmp; } //Hist.print("Hist:");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值