【OpenCV】颜色识别实例(瓶盖)

编程入门 行业动态 更新时间:2024-10-20 18:58:38

【OpenCV】颜色识别实例(<a href=https://www.elefans.com/category/jswz/34/1739028.html style=瓶盖)"/>

【OpenCV】颜色识别实例(瓶盖)

HSV颜色分区参考: 

【OpenCV】HSV颜色识别-HSV基本颜色分量范围

#include <cv.h>
#include <highgui.h>
#include <vector>
using namespace std;
#define MINAREA 600int main()
{IplImage* srcRGB =  cvLoadImage("33333.bmp");IplImage* src= cvCreateImage(cvGetSize(srcRGB), 8, 1);	cvCvtColor(srcRGB, src,CV_RGB2GRAY);cvNamedWindow("srcRGB", 0);if(srcRGB!=NULL){cvShowImage("srcRGB",srcRGB);}/**********************************转HSV分离通道**********************************/IplImage* hsv = cvCreateImage(cvGetSize(srcRGB), 8, 3);cvCvtColor( srcRGB, hsv, CV_BGR2HSV );IplImage* img_h = cvCreateImage(cvGetSize(src), 8, 1);IplImage* img_s = cvCreateImage(cvGetSize(src), 8, 1);IplImage* img_v = cvCreateImage(cvGetSize(src), 8, 1);cvSplit(hsv, img_h, img_s, img_v, NULL);cvNamedWindow("img_h", 0);cvShowImage("img_h", img_h);cvNamedWindow("img_s", 0);cvShowImage("img_s", img_s);cvNamedWindow("img_v", 0);cvShowImage("img_v", img_v);cvNamedWindow("Thresh", 0);IplImage* Thresh_img2 = cvCreateImage(cvGetSize(src), 8, 1);IplImage* Thresh_img1 = cvCreateImage(cvGetSize(src), 8, 1);IplImage* Thresh_img = cvCreateImage(cvGetSize(src), 8, 1);cvThreshold(img_s, Thresh_img1, 90, 255, CV_THRESH_BINARY);cvErode( Thresh_img1, Thresh_img1, NULL, 2 );cvDilate(Thresh_img1, Thresh_img1, NULL, 2);cvNamedWindow("img_ED", 0);cvShowImage("img_ED", Thresh_img1);cvShowImage("Thresh", Thresh_img1);cvWaitKey(0);cvThreshold(img_v, Thresh_img2, 248, 255, CV_THRESH_BINARY);cvAdd(Thresh_img1,Thresh_img2, Thresh_img);cvNamedWindow("img_ADD", 0);cvShowImage("img_ADD", Thresh_img);/***********************************提取目标*************************************/IplImage* temp = cvCreateImage(cvGetSize(src), 8, 1);IplImage* dst = cvCreateImage(cvGetSize(src), 8, 1);IplImage* dstRGB = cvCreateImage(cvGetSize(src), 8, 3);cvZero(dstRGB);cvZero(temp);cvZero(dst);CvMemStorage* storage = cvCreateMemStorage(0);  CvSeq* contour = 0;CvPoint center[20] = {cvPoint(0,0)};int contour_num = cvFindContours(Thresh_img1, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); for(int i = 0; contour != 0; contour = contour->h_next, i++ )    {  double length = cvArcLength(contour);  if(length < MINAREA)     {cvSeqRemove(contour, 0);           // 删除面积小于设定值的轮廓  continue;}  int count = 0;if(length >= MINAREA){count++;cvDrawContours(temp, contour, cvScalar(255,255,255), cvScalar(255,255,255), -1,CV_FILLED); //作为掩码		                     cvCopy(img_h, dst, temp);// cvSeqRemove(contour->h_prev, 0); ///目标区域hue通道的平均灰度值int pix_count=0;int  gray_value = 0;for(int x=0; x<dst->height; x++){uchar* ptr = (uchar*) dst->imageData+x*dst->widthStep;for(int y=0; y<dst->width; y++){				if(ptr[y]){gray_value += ptr[y];pix_count++;}}}gray_value/=pix_count;/找目标中心//CvSeqReader reader;CvPoint pt = cvPoint(0,0);cvStartReadSeq(contour, &reader);int point_count = 0;for(int i=0; i<contour->total; i++){				CV_READ_SEQ_ELEM(pt, reader);center[count].x+=pt.x;center[count].y+=pt.y;point_count++;}center[count].x=center[count].x/point_count;     //中心坐标center[count].y=center[count].y/point_count;cout<<"X:"<<center[count].x << " Y:" << center[count].y<<endl;/cvCopy(srcRGB, dstRGB, temp);		// char* Gray_Value = "hello";// itoa(gray_value, Gray_Value , 20);// sprintf(Gray_Value,"%d",gray_value);// cout<<Gray_Value<<endl;// CvFont font;// cvInitFont(&font, CV_FONT_HERSHEY_DUPLEX, 0.8f, 0.8f, 1, 1);// cvPutText(dstRGB,  Gray_Value, center,	&font, CV_RGB(255,255,255) );cvCircle(dstRGB, center[count], 6, CV_RGB(0,255,0), 2);cout<<gray_value<<endl;cvNamedWindow("dstRGB", 0);cvShowImage("dstRGB", dstRGB);	    }//cvWaitKey(0);} cvWaitKey(0);   cvReleaseImage(&img_h);cvReleaseImage(&img_s);cvReleaseImage(&img_v);	cvReleaseImage(&hsv);cvReleaseImage(&src);cvDestroyAllWindows();
} 

#include "stdafx.h"#include <stdio.h>
#include <iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>using namespace std;
using namespace cv;double GetP2PDis(Point2d p1, Point2d p2);
int FuncCountHSV(Mat mat);int _tmain(int argc, _TCHAR* argv[])
{Mat img = imread("01.bmp");Mat imgSrc;img.copyTo(imgSrc);double time0 = static_cast<double>(getTickCount());    //起始时间const Size size = img.size();int height = size.height;int width = size.width;//---To HSV---//Mat hsv = Mat::zeros(height, width, CV_8UC3);cvtColor(imgSrc, hsv, CV_RGB2HSV);//---分离通道---//vector<cv::Mat> mv;Mat hsv_h = Mat::zeros(height, width, CV_8UC1);Mat hsv_s = Mat::zeros(height, width, CV_8UC1);Mat hsv_v = Mat::zeros(height, width, CV_8UC1);split(hsv, mv);hsv_h = mv.at(0);hsv_s = mv.at(1);hsv_v = mv.at(2);//---S-处理---//Mat matS1 = Mat::zeros(height, width, CV_8UC1);Mat matS2 = Mat::zeros(height, width, CV_8UC1);Mat matS3 = Mat::zeros(height, width, CV_8UC1);Mat element_Se = getStructuringElement(MORPH_ELLIPSE,Size(5,5));Mat element_Sd = getStructuringElement(MORPH_ELLIPSE,Size(5,5));threshold(hsv_s, matS1, 90, 255, CV_THRESH_BINARY);erode( matS1, matS2, element_Se);dilate(matS2, matS3, element_Sd);//---V-处理---//Mat matV1 = Mat::zeros(height, width, CV_8UC1);threshold(hsv_v, matV1, 248, 255, CV_THRESH_BINARY);//---叠加----//Mat matAdd = Mat::zeros(height, width, CV_8UC1);add(matS3, matV1, matAdd);Mat imgDst = matAdd;vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(imgDst, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0,0));  size_t nContoursNum = contours.size();  cout << "轮廓数量:" << nContoursNum << endl;namedWindow("Test1", 0);resizeWindow("Test1", 300, 200);size_t RstNum = 0;for ( size_t index = 0; index < nContoursNum; index++ ){size_t nPerSum = contours[index].size();double dPerimeter = 0.0;  // 轮廓周长for ( size_t i=0; i < nPerSum; i++ ){//----计算周长----//double dCurDis = 0.0;if ( i < nPerSum - 1){dCurDis = GetP2PDis(contours[index].at(i), contours[index].at(i+1) );}else{dCurDis = GetP2PDis(contours[index].at(i), contours[index].at(0) );}dPerimeter += dCurDis;}if ( dPerimeter > 600 ){RstNum++;//-----计算中心坐标-----//int nMinX = contours[index].at(0).x;int nMinY = contours[index].at(0).y;int nMaxX = contours[index].at(0).x;int nMaxY = contours[index].at(0).y;double dSumH = 0.0;for (size_t i = 1; i < nPerSum; i++ ){if ( contours[index].at(i).x > nMaxX ) nMaxX = contours[index].at(i).x;if ( contours[index].at(i).y > nMaxY ) nMaxY = contours[index].at(i).y;if ( contours[index].at(i).x < nMinX ) nMinX = contours[index].at(i).x;if ( contours[index].at(i).y < nMinY ) nMinY = contours[index].at(i).y;//dSumH += imgSrc.ptr<uchar>(contours[index].at(i).y)[contours[index].at(i).x];}Point center;center.x = nMinX + (nMaxX - nMinX) / 2;center.y = nMinY + (nMaxY - nMinY) / 2;cout << "Num: " << RstNum << " Points" << nPerSum << " Length:" << dPerimeter << "----X:" << center.x << " Y:" << center.y<< endl;//------统计颜色-----//int colWidth  = (nMaxX - nMinX);int colHeight = (nMaxY - nMinY);Mat matColorH = Mat::zeros(colWidth, colHeight, CV_8UC1);Mat matColorS = Mat::zeros(colWidth, colHeight, CV_8UC1);Mat matColorV = Mat::zeros(colWidth, colHeight, CV_8UC1);Rect rectROI( nMinX, nMinY, colWidth, colHeight );hsv_h(rectROI).convertTo(matColorH, matColorH.type(), 1, 0);hsv_s(rectROI).convertTo(matColorS, matColorS.type(), 1, 0);hsv_v(rectROI).convertTo(matColorV, matColorV.type(), 1, 0);Scalar mean_h = mean(matColorH);Scalar mean_s = mean(matColorS);Scalar mean_v = mean(matColorV);double dH = mean_h[0];double dS = mean_s[0];double dV = mean_v[0];cout << "H:" << dH << " S:" << dS  << " V:" << dV;// 			if ( dH>0 && dH<180 && dS>0 && dS<255 && dV>0 && dV<46 ) cout << "01黑色 ";
// 			if ( dH>0 && dH<180 && dS>0 && dS<43 && dV>46 && dV<220 ) cout << "02灰色 ";
// 			if ( dH>0 && dH<180 && dS>0 && dS<30 && dV>221 && dV<255 ) cout << "03白色 ";
// 			if ( dH>0 && dH<10 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "04红色 ";
// 			if ( dH>156 && dH<180 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "04红色2 ";
// 			if ( dH>11 && dH<25 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "05橙色 ";
// 			if ( dH>26 && dH<34 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "06黄色 ";
// 			if ( dH>35 && dH<77 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "07绿色 ";
// 			if ( dH>78 && dH<99 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "08青色 ";
// 			if ( dH>100 && dH<124 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "09蓝色 ";
// 			if ( dH>125 && dH<155 && dS>43 && dS<255 && dV>46 && dV<255 ) cout << "10紫色 ";if ( dH>0 && dH<180 ){if ( dH>0 && dH<=10 ) cout << "04红色 ";if ( dH>10 && dH<=25 ) cout << "05橙色 ";if ( dH>25 && dH<=34 ) cout << "06黄色 ";if ( dH>34 && dH<=77 ) cout << "07绿色 ";if ( dH>77 && dH<=99 ) cout << "08青色 ";if ( dH>99 && dH<=124 ) cout << "09蓝色 ";if ( dH>124 && dH<=155 ) cout << "10紫色 ";if ( dH>155 && dH<=180 ) cout << "04红色2 ";if ( dH>0 && dH<180 && dS>0 && dS<255 && dV>0 && dV<46 ) cout << "01黑色 ";if ( dH>0 && dH<180 && dS>0 && dS<43 && dV>46 && dV<220 ) cout << "02灰色 ";if ( dH>0 && dH<180 && dS>0 && dS<43 && dV>221 && dV<255 ) cout << "03白色 ";}cout << endl;cout << endl;imshow("Test1", matColorH);waitKey();
// 			imshow("Test1", matColorS);
// 			waitKey();
// 			imshow("Test1", matColorV);
// 			waitKey();//----绘制结果轮廓----//Scalar color( rand()&255, rand()&255, rand()&255 );drawContours( imgSrc, contours, index, color, 10, 8, hierarchy );circle(imgSrc, center, 5 , color, 5, 8, 0); char str_i[10];sprintf(str_i,"%d",RstNum);putText(imgSrc, str_i, center, CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0,255,0), 2, 8);imwrite("result.bmp", imgSrc);}}time0 = ((double)getTickCount() - time0) / getTickFrequency();    //运行后时间cout << "Run time : " << time0 << endl;// 	imshow("Test1", hsv);
// 	waitKey();
// 
// 	imshow("Test1", hsv_h);
// 	waitKey();
// 	imshow("Test1", hsv_s);
// 	waitKey();
// 	imshow("Test1", hsv_v);
// 	waitKey();
// 
// 	imshow("Test1", matS1);
// 	waitKey();
// 	imshow("Test1", matS2);
// 	waitKey();
// 	imshow("Test1", matS3);
// 	waitKey();
// 
// 	imshow("Test1", matV1);
// 	waitKey();
// 	imshow("Test1", matV2);
// 	waitKey();
// 	imshow("Test1", matV3);
// 	waitKey();
// 
// 	imshow("Test1", matAdd);
// 	waitKey();// 	imshow("Test1", imgDst);
// 	waitKey();imshow("Test1", imgSrc);waitKey();return 0;
}double GetP2PDis(Point2d p1, Point2d p2)
{double dDis = 0.0;dDis = sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y));return dDis;
}


//----------------------------------------------Camera.Size size = mCamera.getParameters().getPreviewSize();final int w = size.width;final int h = size.height;final YuvImage image = new YuvImage(mData, ImageFormat.NV21, w, h, null);ByteArrayOutputStream os = new ByteArrayOutputStream(mData.length);if (!imagepressToJpeg(new Rect(0, 0, w, h), 100, os)) {return;}byte[] tmp = os.toByteArray();Bitmap bitmap = BitmapFactory.decodeByteArray(tmp, 0, tmp.length);Bitmap input = rotateBitmap(bitmap, 90);Bitmap bmp = input.copy(Bitmap.Config.ARGB_8888, true);int nw = bmp.getWidth();int nh = bmp.getHeight();int[] pix = new int[nw * nh];bmp.getPixels(pix, 0, nw, 0, 0, nw, nh);int[] resultPixels = OpenCVHelper.colorDetection(pix, nw, nh);Bitmap result = Bitmap.createBitmap(nw, nh, Bitmap.Config.RGB_565);result.setPixels(resultPixels,0,nw,0,0,nw,h);image_show.setImageBitmap(result);



JNIEXPORT jintArray JNICALL Java_com_example_targetlocationapp_OpenCVHelper_colorDetection(JNIEnv *env, jclass obj, jintArray  buf, jint w, jint h){jint *cbuf;cbuf = env->GetIntArrayElements(buf,JNI_FALSE);if (NULL == cbuf){return 0;}Mat srcImage(h,w,CV_8UC4,(unsigned char*) cbuf);Mat rgbImage;cvtColor(srcImage, rgbImage, COLOR_BGRA2RGB);for (size_t i = 0; i < 5; i++){Point center(100 + 50*i, 150 + 30*i);ellipse(rgbImage, center, Size(100, 150), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);}int size = w * h;jintArray result = env->NewIntArray(size);//jint *pArrayBuf = env->GetIntArrayElements(result, nullptr);u_char *ptr = rgbImage.ptr(0);u_char *ptrRst = srcImage.ptr(0);for(int i=0;i < size; i++){// int grayScale = (int)(ptr[3*i+2]*0.299 + ptr[3*i+1]*0.587 + ptr[3*i+0]*0.144 );// pArrayBuf[i] = (int)ptr[3*i+2];ptrRst[4*i+0] = (int)ptr[3*i+2];ptrRst[4*i+1] = (int)ptr[3*i+1];ptrRst[4*i+2] = (int)ptr[3*i+0];}env->SetIntArrayRegion(result,0,size,cbuf);env->ReleaseIntArrayElements(buf,cbuf,0);return result;
}


JNIEXPORT jintArray JNICALL Java_com_example_app_OpenCVHelper_colorDet(JNIEnv *env, jclass obj, jbyteArray  yuv, jint w, jint h){jbyte * pBuf = (jbyte*)env->GetByteArrayElements(yuv, 0);int width = w;int height = h + h /2;cv::Mat imageSrc(height, width , CV_8UC1, (unsigned char*)pBuf );cv::Mat imageBGR;cv::cvtColor(imageSrc, imageBGR, CV_YUV2BGR_NV21); //将YUV转换成BGRcv::Mat srcSize;cv::resize(imageBGR, srcSize, Size(h/20, w/20));cv::Mat timage;cv::transpose(imageBGR, timage);  //图像转置cv::Mat yimage;cv::flip(timage, yimage, 1);   //Y方向镜像//---------图像处理---------cv::Mat image(yimage);cv::Mat frameHSV;cv::medianBlur(image, image, 5);cv::cvtColor(image, frameHSV, CV_BGR2HSV);cv::Mat dstTemp1(image.rows, image.cols, CV_8UC1);cv::Mat dstTemp2(image.rows, image.cols, CV_8UC1);cv::inRange(frameHSV, Scalar(0,30,30), Scalar(40,170,256), dstTemp1);cv::inRange(frameHSV, Scalar(156, 30, 30), Scalar(180, 170, 256), dstTemp2);cv::Mat mask(image.rows, image.cols, CV_8UC1);  // 2值掩膜cv::add(dstTemp1, dstTemp2, mask);// 形态学操作,去除噪声,并使手的边界更加清晰cv::Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));cv::erode(mask, mask, element);cv::morphologyEx(mask, mask, MORPH_OPEN, element);cv::dilate(mask, mask, element);cv::morphologyEx(mask, mask, MORPH_CLOSE, element);cv::vector<cv::vector<cv::Point>> contours;	// 轮廓cv::vector<cv::Vec4i> hierarchy;	// 轮廓的结构信息cv::vector<cv::vector<cv::Point>> filterContours;	// 筛选后的轮廓contours.clear();hierarchy.clear();filterContours.clear();Mat maskDst = mask;// 得到手的轮廓//CV_RETR_EXTERNAL 只检测出最外轮廓即c0。图2中第一个轮廓指向最外的序列,除此之外没有别的连接。//CV_RETR_LIST 检测出所有的轮廓并将他们保存到表(list)中,图2中描绘了这个表,被找到的9条轮廓相互之间由h_prev和h_next连接。//CV_RETR_COMP 检测出所有的轮廓并将他们组织成双层的结构,第一层是外部轮廓边界,第二层边界是孔的边界。//CV_RETR_TREE 检测出所有轮廓并且重新建立网状的轮廓结构。cv::findContours(mask, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));size_t nContoursNum = contours.size();size_t nCountNum = 0;// 去除伪轮廓cv::Mat dst(image.rows, image.cols, CV_8UC3);for (size_t i = 0; i < contours.size(); i++){cv::Scalar color(rand() & 255, rand() & 255, rand() & 255);cv::drawContours(dst, contours, i, color, CV_FILLED, 8, hierarchy);}cv::Mat dstSize;cv::resize(dst, dstSize, Size(h, w));const int size = w * h;jintArray result = env->NewIntArray(size);jint* pArrayBuf = env->GetIntArrayElements(result, nullptr);Mat dstShow(h, w, CV_8UC4, (unsigned char* )pArrayBuf);u_char* ptr = dstSize.ptr(0);u_char* ptrRst = dstShow.ptr(0);for(int i=0;i<size;i++){memcpy(ptrRst+4*i+0, ptr+3*i+0, sizeof(u_char));memcpy(ptrRst+4*i+1, ptr+3*i+1, sizeof(u_char));memcpy(ptrRst+4*i+2, ptr+3*i+2, sizeof(u_char));}env->SetIntArrayRegion(result, 0, size, pArrayBuf);env->ReleaseIntArrayElements(result, pArrayBuf, 0);env->ReleaseByteArrayElements(yuv, pBuf, 0);return result;
}

更多推荐

【OpenCV】颜色识别实例(瓶盖)

本文发布于:2024-03-14 04:04:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1735582.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:瓶盖   实例   颜色   OpenCV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!