- åè¨
- Schneider ç¼ç æ¹æ¡ä»ç»
- è¯å«ç¨åºæµç¨å¾
- è¯å«ä»£ç å±ç¤º
- 主å½æ°
- æ¾æå°ç¼ç åå½æ°
- opencvå¾çæå ¥ä¸æå½æ°
- è¯å«ææ
- ä¸è½½å°å
åè¨
å¨æ°åè¿æ¯æå½±æµéä¸ï¼æå ³é®çå¾åé´çå¹é ãä½æ¯ç±äºå·¥ä¸æµéç°åºå¤æçèæ¯å被æµç©ä½è¡¨é¢æ²¡æ足å¤çç¹å¾ï¼åºç¨å¨åç®è§è§ä¸åºäºå ³é®ç¹å¹é çç®æ³å¨æçã精度ãåç¡®ççæ¹é¢ï¼å¤§å¤ä¸è½æ»¡è¶³éæ±ãäºæ¯å¨å·¥ä¸æ°åè¿æ¯æµéä¸éè¦äººå·¥è®¾ç½®çé¶æ ç¹ä½ä¸ºå ³é®ç¹è¿è¡å¹é ã
人工设置çé¶æ æå¾å¤ç§ï¼ç®åæ主è¦çç¹åå¸åï¼åå¿åç¯åï¼éå ä½ç¹å¾åãæ¬æå©ç¨ç¨åºå®ç°äºåå¿åç¯åä¸Schneider C .T设计çé¶æ çèªå¨çæã
å¨ä¸ä¸ç¯æç« ï¼https://blog.csdn.net/iamqianrenzhan/article/details/81194791ï¼ä¸ä»ç»äºä¸åèªå¨çæSchneiderç¼ç æ å¿çç¨åºï¼è¿ä¸ç¯ä¸»è¦ä»ç»æä¹è¯å«ç¸æºæå°çç¼ç é¶æ ã
Schneider ç¼ç æ¹æ¡ä»ç»
Schneider ç¼ç æ¹æ¡ä»ç»å®ç±ä¸å¿åååå¿ç¼ç ç¯å¸¦ç»æï¼ç¼ç ç¯å¸¦æç §è§åº¦åå为10份ï¼æ¯ä»½36°ï¼æ¯ä¸ä»½å¯ä»¥ç§°ä¸ºäº®ç¯å¸¦æè æç¯å¸¦ï¼ç¸åºçäºè¿å¶ç 为1æè 0ï¼â1â表示该ä½ä¸æç¼ç ç¹ï¼â0â表示该ä½ä¸æ²¡æç¼ç ç¹ï¼ç±äºç¼ç ç¯å¸¦å¹¶æ²¡æè§å®èµ·å§ç¹ï¼ä»¥ä»»æä¸ä¸ªç¼ç ç¹ä¸ºèµ·å§ä½ç½®ï¼æ顺æ¶éæ¹å读åç¼ç ç¯å¸¦çç å¼ï¼ å¯ä»¥ç»æé¿åº¦ä¸º 10çäºè¿å¶åºåï¼å¯¹è¿ä¸ªäºè¿å¶åºåè¿è¡å¾ªç¯ç§»ä½ï¼éåå ¶ä¸æ°å¼æå°çäºè¿å¶åºåä½ä¸ºè¯¥é¶æ çç å¼ã
è¯å«ç¨åºæµç¨å¾
å ¶ä¸çéæ¤åè½®å»ä¸æ¥ç®åè¿ä¸è½å¾å¥½å®ç°ãåªè½çéåºåå½¢çè½®å»ï¼æ以对大è§åº¦æå½±ææçè¯å«çå¾ä½ãè¿éè¦å ³æ³¨çæ¯è·åç¼ç å¼è¿æ¥ï¼å 为è¦åæ8个åºå并ä¸ä¸ç¥éåºåçèµ·ç¹ï¼æ以ç¨åºä¸å®ç°æ¹æ¡æ¯å¨45度çèå´å æ¯é15度éæ©ä¸ä¸ªèµ·ç¹ï¼è¿æ ·å¯¹äºææææè¾å¥½çå¾çï¼ä¼å¾å°3个ç¸åçç¼ç å¼ï¼é£å°±ç¡®å®äºé¶æ çç¼ç å¼ï¼å¯¹äºææææä¸å¥½çå¾çï¼ä¼å¾å°2个ç¸åçç¼ç å¼ï¼ä¹å¯ä»¥ç¡®å®äºé¶æ çç¼ç å¼ã
è¯å«ä»£ç å±ç¤º
主å½æ°
int main()
{
bool debug = ;
//读åå¾ç
//string filename = "8/all.jpg";
string filename = "35.bmp";
Mat img = imread(filename);
if (debug)
{
namedWindow("åå¾", );
imshow("åå¾", img);
waitKey();
}
//æä¹å¤ç
åéå®ä¹
Mat gray_all = img;
vector<vector<cv::Point> > contours_all, contours_circle;
vector<cv::Vec4i> hierarchy_all;
//æ¾å°ææè½®å»
cvtColor(gray_all, gray_all, CV_BGR2GRAY);
GaussianBlur(gray_all, gray_all, cv::Size(, ), );
threshold(gray_all, gray_all, , , THRESH_BINARY);
Mat gray_show = gray_all.clone();
cv::findContours(gray_all, contours_all, hierarchy_all, CV_RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point(, ));
if (debug)
{
//ç»å¶ææè½®å»
Mat temp1 = Mat::zeros(gray_all.size(), CV_8UC3);
drawContours(temp1, contours_all, -, CV_RGB(, , ), );
namedWindow("æ¾å°çææè½®å»", );
imshow("æ¾å°çææè½®å»", temp1);
waitKey();
}
//ä»ææè½®å»ä¸æ¾åºåï¼å¾å°åå¿ååå¾ï¼ä½ä¸ºåç»å¤ç
//è¿é¨å代ç å¯ä»¥ä¼åï¼å¾å°æ¤åçä¸å¿åé¿çè½´ï¼è§åº¦ï¼è¿æ ·å¯ä»¥å¤çä¸æ¯æ£æå½±çæ
åµã
vector<Point2f> vec_center;
vector<float> vec_radius;
vector<RotatedRect> vec_rrect;
for (int i = ; i < contours_all.size(); i++)
{
Point2f center;
float radius;
minEnclosingCircle(contours_all[i], center, radius);//æå°å¤æ¥åï¼æå°å¤æ¥æ¤åæ¯å¦å¯è¡ï¼
float contourarea = contourArea(contours_all[i]);
float ratio1 = contourarea / (*radius*radius);
if (ratio1 > &&contours_all[i].size() > ) //æ0.85è°å°å¯ä»¥è¯å«å°æ´å¤çåï¼ä½ä¼å¢å 误è¯å«æ¦ç
{
contours_circle.push_back(contours_all[i]);
cout << "ratio1:" << ratio1 << endl;
vec_center.push_back(center);
vec_radius.push_back(radius);
}
//æåæ转ç©å½¢
if (contours_all[i].size() > )
{
RotatedRect fitelliprect = fitEllipse(contours_all[i]);
RotatedRect minarearect = minAreaRect(contours_all[i]);
float fitrectarea = fitelliprect.size.width * fitelliprect.size.height;
float mimarea = minarearect.size.width * minarearect.size.height;
float ratio2 = fitrectarea / mimarea;
if (ratio2 > && ratio2 < ) //è¿è¦åå æ¡ä»¶
{
cout << "ratio2:" << ratio2 << endl;
vec_rrect.push_back(fitelliprect);
}
}
}
//ç»å¶æåæ¤åç©å½¢
if (debug)
{
Mat temp2 = Mat::zeros(gray_all.size(), CV_8UC3);
for (int i = ; i < vec_rrect.size(); i++)
{
circle(temp2, vec_rrect[i].center, , cv::Scalar(, , ), -);
}
namedWindow("æ¤åç©å½¢", );
imshow("æ¤åç©å½¢", temp2);
}
//ç»å¶åè½®å»
if (debug)
{
Mat temp3 = Mat::zeros(gray_all.size(), CV_8UC3);
drawContours(temp3, contours_circle, -, CV_RGB(, , ), );
namedWindow("æ¾å°çåè½®å»", );
imshow("æ¾å°çåè½®å»", temp3);
}
//ä»åè½®å»ä¸æªååºé¶æ åºå
for (int i = ; i < vec_center.size(); i++)
{
cout << "第" << i << "个ç¹å¾" << endl;
Rect rect = Rect(vec_center[i].x - * vec_radius[i],
vec_center[i].y - * vec_radius[i],
* vec_radius[i],
* vec_radius[i]);
//éè¦åå¤ææ¯å¦è¶
åºè¾¹ç
Mat t = gray_show(rect);
//å¤çé¶æ åºå,ä»é¶æ ä¸å¿é¡ºæ¶éæ¹åé45度æ«æ;3ç§æ«æèµ·ç¹,0,15,30
uint8_t codenew = ;
for (int ScanningPoint = ; ScanningPoint < ; ScanningPoint++)
{
uint8_t code = ;
//æ¯é45度ç®ä¸ä¸ªåºå,å
±8个åºå
for (int range = ; range < ; range++)
{
int count = ;
int StartPoint = range * + ScanningPoint * ;
int EndPoint = (range+) * + ScanningPoint * ;
for (int angle = StartPoint; angle < EndPoint; angle = angle + )
{
Point2f p = Point2f( * vec_radius[i] + (vec_radius[i] / * )*cos(angle / *),
* vec_radius[i] + (vec_radius[i] / * )*sin(angle / *));
uchar x = t.at<uchar>((int)p.x, (int)p.y);
if ((int)x == )
count++;
}
if (count < ) //说æ该ä½æ¯1 if (count > 7) //åå³äºæ¯å¦åè²ï¼å¯ä»¥æ ¹æ®ä¸å¿åç´ å¤æ)
{
code += pow(, range);
}
}
codenew = findmincode(code);
cout << (int)codenew << endl;
cout << "转9度" << endl << endl;
}
//å¨tä¸åæ°å
Point origin;
string str0 = to_string((int)codenew);
const char* text0 = str0.c_str();
//ææ¬æ¡ä½ç½®
origin.x = * vec_radius[i]-;
origin.y = * vec_radius[i]-;
putTextZH(t, text0, origin, Scalar(, , ), , "Arial", , );
//æ¾ç¤ºé¶æ åºå
if (debug)
{
string title = to_string(i);
namedWindow(title);
imshow(title, t);
waitKey();
}
cout << endl << endl;
}
waitKey();
while ();
return ;
}
æ¾æå°ç¼ç åå½æ°
//é¶æ åå§ç¼å·éå左移æ¾å°æå°çç¼å·ï¼è¿æ¯è¯¥ç¼ç é¶æ çç¼ç è§åã
uint8_t findmincode(uint8_t code)
{
uint8_t minresult = ;
for (int i = ; i < ; i++)
{
uint8_t a = code;
uint8_t left = ;//åå¨å·¦ç§»ä¹åçç»æ
uint8_t right = ;//åå¨å³ç§»ä¹åçç»æ
right = (a >> i);
left = a << ( - i);
uint8_t result;
result = left | right;
if (result < minresult)
{
minresult = result;
}
}
return minresult;
}
opencvå¾çæå ¥ä¸æå½æ°
void GetStringSize(HDC hDC, const char* str, int* w, int* h)
{
SIZE size;
GetTextExtentPoint32A(hDC, str, strlen(str), &size);
if (w != ) *w = size.cx;
if (h != ) *h = size.cy;
}
void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline)
{
CV_Assert(dst.data != && (dst.channels() == || dst.channels() == ));
int x, y, r, b;
if (org.x > dst.cols || org.y > dst.rows) return;
x = org.x < ? -org.x : ;
y = org.y < ? -org.y : ;
LOGFONTA lf;
lf.lfHeight = -fontSize;
lf.lfWidth = ;
lf.lfEscapement = ;
lf.lfOrientation = ;
lf.lfWeight = ;
lf.lfItalic = italic; //æä½
lf.lfUnderline = underline; //ä¸å线
lf.lfStrikeOut = ;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = ;
lf.lfClipPrecision = ;
lf.lfQuality = PROOF_QUALITY;
lf.lfPitchAndFamily = ;
strcpy_s(lf.lfFaceName, fn);
HFONT hf = CreateFontIndirectA(&lf);
HDC hDC = CreateCompatibleDC();
HFONT hOldFont = (HFONT)SelectObject(hDC, hf);
int strBaseW = , strBaseH = ;
int singleRow = ;
char buf[ << ];
strcpy_s(buf, str);
char *bufT[ << ]; // è¿ä¸ªç¨äºåéå符串åå©ä½çå符ï¼å¯è½ä¼è¶
åºã
//å¤çå¤è¡
{
int nnh = ;
int cw, ch;
const char* ln = strtok_s(buf, "\n", bufT);
while (ln != )
{
GetStringSize(hDC, ln, &cw, &ch);
strBaseW = max(strBaseW, cw);
strBaseH = max(strBaseH, ch);
ln = strtok_s(, "\n", bufT);
nnh++;
}
singleRow = strBaseH;
strBaseH *= nnh;
}
if (org.x + strBaseW < || org.y + strBaseH < )
{
SelectObject(hDC, hOldFont);
DeleteObject(hf);
DeleteObject(hDC);
return;
}
r = org.x + strBaseW > dst.cols ? dst.cols - org.x - : strBaseW - ;
b = org.y + strBaseH > dst.rows ? dst.rows - org.y - : strBaseH - ;
org.x = org.x < ? : org.x;
org.y = org.y < ? : org.y;
BITMAPINFO bmp = { };
BITMAPINFOHEADER& bih = bmp.bmiHeader;
int strDrawLineStep = strBaseW * % == ? strBaseW * : (strBaseW * + - ((strBaseW * ) % ));
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = strBaseW;
bih.biHeight = strBaseH;
bih.biPlanes = ;
bih.biBitCount = ;
bih.biCompression = BI_RGB;
bih.biSizeImage = strBaseH * strDrawLineStep;
bih.biClrUsed = ;
bih.biClrImportant = ;
void* pDibData = ;
HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, , );
CV_Assert(pDibData != );
HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);
//color.val[2], color.val[1], color.val[0]
SetTextColor(hDC, RGB(, , ));
SetBkColor(hDC, );
//SetStretchBltMode(hDC, COLORONCOLOR);
strcpy_s(buf, str);
const char* ln = strtok_s(buf, "\n", bufT);
int outTextY = ;
while (ln != )
{
TextOutA(hDC, , outTextY, ln, strlen(ln));
outTextY += singleRow;
ln = strtok_s(, "\n", bufT);
}
uchar* dstData = (uchar*)dst.data;
int dstStep = dst.step / sizeof(dstData[]);
unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
unsigned char* pStr = (unsigned char*)pDibData + x * ;
for (int tty = y; tty <= b; ++tty)
{
unsigned char* subImg = pImg + (tty - y) * dstStep;
unsigned char* subStr = pStr + (strBaseH - tty - ) * strDrawLineStep;
for (int ttx = x; ttx <= r; ++ttx)
{
for (int n = ; n < dst.channels(); ++n) {
double vtxt = subStr[n] / ;
int cvv = vtxt * color.val[n] + ( - vtxt) * subImg[n];
subImg[n] = cvv > ? : (cvv < ? : cvv);
}
subStr += ;
subImg += dst.channels();
}
}
SelectObject(hDC, hOldBmp);
SelectObject(hDC, hOldFont);
DeleteObject(hf);
DeleteObject(hBmp);
DeleteDC(hDC);
}
è¯å«ææ
注ï¼ç±äºå±å¹å¤§å°éå¶ï¼è¿éçæªå¾å¹¶æ²¡ææææè¯å«å°çé¶æ å±ç¤ºåºæ¥ã
ä¸è½½å°å
https://download.csdn.net/download/iamqianrenzhan/10565628