double *hough(struct IplImage *frame) { int x, y, r, w, h, maxrad; double diag; double *accarr; unsigned char thres; //quantization(frame); h = frame->height; w = frame->width; diag = sqrt(w * w + h * h); maxrad = h; thres = otsu(frame); accarr = malloc(sizeof(double) * w * h * maxrad); bzero(accarr, w * h * maxrad); for(y = 0; y < h; y++){ for(x = 0; x < w; x++) { double gx, gy, gr; double theta; int x0, y0; grad(frame->data, w, h, x, y, &gx, &gy); theta = atan2(gy, gx); gr = sqrt(gx * gx + gy * gy); if (gr >= (thres + MEASURE_ERROR)) { for (r = 100; r < maxrad; r++) { x0 = x - r * cos(theta); y0 = y - r * sin(theta); if (x0 >= 0 && y0 >= 0 && x0 < w && y0 < h) accarr[(y0 * h + x0) * r]++; } } } } //double avr = 0.0; double max; max = 0; for(r = 10; r < maxrad; r++) for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (accarr[(y * w + x) * r] >= max) max = accarr[(y * w + x) * r]; // avr += accarr[(y * w + x) * r]; // avr /= (w * h * (maxrad - 10)); // printf("%lf\n", avr); for(r = 100; r < maxrad; r++) for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (accarr[(y * w + x) * r] < max) accarr[(y * w + x) * r] = 0.0; return accarr; }
//找最大的团并返回外轮廓 std::vector<MYPOINT> FindBiggestContour(cimg_library::CImg<unsigned char> origin, std::vector<MYPOINT> Points) { std::vector<MYPOINT> contour; cimg_library::CImg<unsigned char> mask; //compute the binary img int threshold = otsu(origin, Points, mask, 1); unsigned char *bi_img = new unsigned char[origin.width()*origin.height()]; for (int i = 0; i < origin.height(); i++){ for (int j = 0; j < origin.width(); j++){ if (origin.atXY(j, i) >= threshold && mask.atXY(j, i) == 255) bi_img[i*origin.width() + j] = 255; else bi_img[i*origin.width() + j] = 0; } } //返回二值图像 cimg_library::CImg<unsigned char> bi(bi_img, origin.width(), origin.height()); //done //找团 std::vector<int> stRun, enRun, rowRun, masRun; int NumberofRuns = 0, offset = 1, maxRun = 1; fillRunVector(bi, NumberofRuns, stRun, enRun, rowRun, masRun); std::vector<int> runLabels; std::vector<std::pair<int, int>> equivalences; firstPass(stRun, enRun, rowRun, NumberofRuns, runLabels, equivalences, offset); if (!NumberofRuns){ std::cout << "NOTHING FOUND!!!" << std::endl <<"size of contour is: "<< contour.size() << std::endl; return contour; } replaceSameLabel(runLabels, equivalences); int maxLabel = *max_element(runLabels.begin(), runLabels.end()); int *MassofRuns = new int[maxLabel + 1]; memset(MassofRuns, 0, (maxLabel + 1)*sizeof(int)); memset(bi_img, 0, (bi.height()*bi.width())*sizeof(unsigned char)); for (int c = 0; c < NumberofRuns; c++){ MassofRuns[runLabels[c]] += masRun[c]; if (MassofRuns[runLabels[c]]>maxRun){ maxRun = MassofRuns[runLabels[c]]; maxLabel = runLabels[c]; } int i = rowRun[c]; for (int j = stRun[c]; j <= enRun[c]; j++){ bi_img[i*bi.width() + j] = runLabels[c]; } } for (int i = 0; i < bi.height(); i++) for (int j = 0; j < bi.width(); j++) { if (bi_img[i*bi.width()+j] == maxLabel) bi_img[i*bi.width() + j] = 255; else bi_img[i*bi.width() + j] = 0; } return FindContour(bi_img, bi.width(), bi.height()); }
int main(int argc, char* argv[]) { if (argc == 1) { return 0; } ClImgBMP img; img.LoadImage(argv[1]); otsu(img.imgData.begin(), img.imgData.end()); string path = argv[1]; path.insert(path.size() - 4, "[otsu]"); img.SaveImage(path.c_str()); return 1; }
void histogram(cv::Mat *image,int *histo, int convert){ if (!image || !histo) return; unsigned char *im = (unsigned char*)(image->data); int im_step = image->step; int im_cols = image->cols; int im_rows = image->rows; histogram(im,im_step,im_cols,im_rows,histo); if (convert) { otsu(im,im_step,im_cols,im_rows,histo); } }
void otsuN(IplImage* img, IplImage* img_seg, int modes, double **thr, double* sep) { int _verbose=1; int xsize = img->width; int ysize = img->height; double* data=new double[xsize * ysize]; for (int i = 0; i < ysize; i++) for (int j = 0; j < xsize; j++) { CvScalar c = cvGet2D(img, i, j); data[i * xsize + j] = c.val[0] / 255.0; } if(_verbose) printf("img: %d %d %d %d\n",xsize,ysize,img->nChannels,img->depth); double* Iseg=new double[xsize * ysize]; otsu(Iseg, thr, sep, data, xsize, ysize, modes); for (int i = 0; i < ysize; i++) for (int j = 0; j < xsize; j++) { CvScalar c; double v = Iseg[i * xsize + j]; c.val[0] = v * 255; c.val[1] = v * 255; c.val[2] = v * 255; cvSetAt(img_seg, c, i, j); } if(_verbose) { double_vector_save_to_file("data.txt", xsize*ysize, data); double_vector_save_to_file("data_out.txt", xsize*ysize, Iseg); double_vector_save_to_file("thr.txt", modes-1, *thr); std::cout << "thr = "; double_vector_print(modes-1, *thr); std::cout<< "Criterio de separabilidad: " << *sep << std::endl; } delete[] Iseg; delete[] data; }
int findGlobalOtsu3DImage(MATRIX3 M){ int maxNo = maxMatrix3Entry(M) + 1; double *p = (double *)calloc(maxNo,sizeof(double)); int i, j, k, thr; for (k = 0; k < M.d1; k++) for (i = 0; i < M.d2; i++) for (j = 0; j < M.d3; j++) p[ M.data[k][i][j] ]++; for (i = 0; i < maxNo; i++) p[i] /= (M.d1 * M.d2 * M.d3); thr = otsu(p,maxNo); free(p); return thr; }
void MainWindow::on_actionOtsu_global_triggered() { QPixmap pixmap = pixmapItem->pixmap().copy(); QImage image = pixmap.toImage(); int width = image.width(); int height = image.height(); if (width == 0 || height == 0) { ui->statusBar->showMessage( tr("Error. Image bad size"), 3000 ); return; } std::vector<int> grays(width * height, 0); int finalThreshold = otsu(image, grays, 0, 0, width, height); QRgb black = qRgb(0,0,0); QRgb white = qRgb(255,255,255); QRgb newColor; for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x) { int gray = grays[x + y * width]; if ( gray < finalThreshold ) newColor = black; else newColor = white; image.setPixel(x, y, newColor); } pixmap.convertFromImage(image); pixmapItem_2->setPixmap(pixmap); scene_2->setSceneRect(QRectF(pixmap.rect())); calcHist(pixmap, hist_2, maxLevel_2); drawHist(pixmapItem_4, hist_2, maxLevel_2); }
int main() { Mat src = imread("D:\\pictures\\potato.png"); imshow("origin", src); Mat dst = Otsu(src); int height = dst.cols; int width = dst.rows; uchar* imagedata = new uchar[height * width](); for (int i = 0; i < width; i++){ for (int j = 0; j < height; j++){ imagedata[i * height + j] = dst.at<uchar>(i, j) > 0 ? 1 : 0; } } GetSkeleton(imagedata, height, width); for (int i = 0; i < width; i++){ for (int j = 0; j < height; j++){ dst.at<uchar>(i, j) = imagedata[i * height + j] > 0 ? 0 : 255; } } cvtColor(src, src, CV_RGB2GRAY); Mat sdst, dst1, dst2; dst1 = Boundary(src); Mat BigBlankimage = Mat::ones(src.rows, src.cols, CV_8UC1); dst2 = BigBlankimage * 255 - dst1; int threhold = otsu(dst1) - 28; threshold(dst1, sdst, threhold, 255, CV_THRESH_BINARY); sdst = BigBlankimage * 255 - sdst; imshow("skin", sdst); imshow("skeleton", dst); waitKey(); }
void ProcessFrame(uint8 *pInputImg) { uint8_t thres = (uint8_t)data.ipc.state.nThreshold; /* if the threshold is 0, the otsu algorithm is used */ if(thres == 0) { thres = otsu(IMAGE(GRAYSCALE)); } data.ipc.state.thres_calc = thres; /* make the threshold image */ thresh(IMAGE(THRESHOLD), IMAGE(GRAYSCALE), thres); /* dilation */ dilation(IMAGE(DILATION), IMAGE(THRESHOLD)); /* erosion */ erosion(IMAGE(EROSION), IMAGE(DILATION)); /* do the region labeling stuff */ region_labeling(IMAGE(LABELIMG)); }
void CvScan::charsImgSegement(IplImage *src, vector<IplImage*> &vector) { if (src == NULL) { return; } IplImage *pimg = cvCreateImage(cvSize(src->width*1.1, src->height*1.1), src->depth, src->nChannels); //* int m_otsu = otsu(pimg); printf("m_otsu:%d\n",m_otsu); cvReleaseImage(&pimg); cvZero(pimg); pimg = cvCreateImage(cvGetSize(src), src->depth, src->nChannels); cvThreshold(src, pimg, m_otsu, 255, CV_THRESH_BINARY); //查看 ret:right //vector.push_back(pimg); //return; //*/ std::vector<CvRect> contours; CvSeq* contour; CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner scanner= cvStartFindContours(pimg,storage,sizeof(CvContour),CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0)); //开始遍历轮廓树 CvRect rect; double tmparea = 0.0;double indexArea = 0.0;double minarea = 5*5;double pixels = pimg->width*pimg->height; int i = 0;uchar *pp;IplImage *pdst; while ((contour = cvFindNextContour(scanner))) { tmparea = fabs(cvContourArea(contour)); indexArea = fabs(cvContourArea(contour)/pixels); rect = cvBoundingRect(contour,0); // if (indexArea < 0.02 || indexArea >= 1 || tmparea < minarea) { // //不符合条件 删除区域 // cvSubstituteContour(scanner, NULL); // }else{ // contours.push_back(rect); // } //* if (tmparea<minarea){ //当连通区域的中心点为白色时,而且面积较小则用黑色进行填充 pp=(uchar*)(pimg->imageData+pimg->widthStep*(rect.y+rect.height/2)+rect.x+rect.width/2); if (pp[0]==255){ for (int y=rect.y;y<rect.y+rect.height;y++){ for (int x=rect.x;x<rect.x+rect.width;x++){ pp=(uchar*)(pimg->imageData+pimg->widthStep*y+x); if(pp[0]==255){ pp[0]=0; } } } } }else{ contours.push_back(rect); }; //*/ } cvEndFindContours(&scanner); int size = (int)contours.size(); if (size <= 0) { return; } printf("检测出的矩形个数:%d\n",size); std::vector<CvRect> sortedRect; ////对符合尺寸的图块按照从左到右进行排序 sortRect(contours, sortedRect); for (i = 0; i < sortedRect.size(); i++) { //printf("找到的rect:%d-%d-%d-%d\n",sortedRect[i].x,sortedRect[i].y,sortedRect[i].width,sortedRect[i].height); pdst = cvCreateImage(cvSize(sortedRect[i].width,sortedRect[i].height), IPL_DEPTH_8U, 1); cvSetImageROI(pimg, sortedRect[i]); //cvAdd(pimg, pdst, pdst, NULL); cvCopy(pimg, pdst, NULL); //cvReleaseImage(&pdst); cvResetImageROI(pimg); if (verifyImgCharSizes(pdst)) { IplImage *dst = cvCreateImage(cvSize(kTrimmedCharacterImageWidth, kTrimmedCharacterImageHeight), pdst->depth, pdst->nChannels); cvResize(pdst, dst, CV_INTER_LINEAR); vector.push_back(dst); cvReleaseImage(&pdst); } } //printf("共找到%d个字符块\n",i); }
main(int argc, char *argv[]) { int rows, cols; unsigned char *image; unsigned char *output; float *edge_mag; FILE * fp; int i,j; if (argc != 3){ printf("Usage: Test <input_filename> <output_filename> \n"); printf(" <input_filename>: PGM file \n"); printf(" <output_filename>: PGM file \n"); printf(" <output2_filename>: PGM file \n"); exit(0); } printf("Reading PGM.... \n"); if ((fp=fopen(argv[1], "rb"))==NULL){ printf("reading error...\n"); exit(0); } ReadPGM(fp,&image,&rows,&cols); /* you may replace your own applications here */ edge_mag = (float*)malloc(sizeof(float)*rows*cols); /* printf("begin calculting edge_magnitude.... \n"); EdgeMag(rows, cols, image, edge_mag); */ // copy the data for (j=0; j<rows; j++) { for (i=0; i<cols; i++) { edge_mag[j*cols+i] = image[j*cols+i]; } } otsu(2,2,cols,rows,edge_mag); /* end of your application */ output = (unsigned char*)malloc(sizeof(unsigned char)*cols*rows); for (j=0; j<rows; j++) for (i=0; i<cols; i++) output[j*cols+i] = (unsigned char)edge_mag[j*cols+i]; if ((fp=fopen(argv[2], "wb"))==NULL){ printf("reading error...\n"); exit(0); } printf("Writing PGM....\n"); WritePGM(rows, cols, image, output, fp); /* output2 = (unsigned char*)malloc(sizeof(unsigned char)*256*256); for (j=0; j<256; j++) for (i=0; i<256; i++) output2[j*255+i] = (unsigned char)edge_mag_histo[j*255+i]; if ((fp=fopen(argv[3], "wb"))==NULL){ printf("reading error...\n"); exit(0); } printf("Writing PGM....\n"); WritePGM(rows, cols, image, output2, fp); */ }
void MainWindow::on_actionOtsu_local_triggered() { QPixmap pixmap = pixmapItem->pixmap().copy(); QImage image = pixmap.toImage(); int width = image.width(); int height = image.height(); if (width == 0 || height == 0) { ui->statusBar->showMessage( tr("Error. Image bad size"), 3000 ); return; } DialogOtsuLocal dialog; dialog.setSpinBoxes(pixmapItem->pixmap().width(), pixmapItem->pixmap().height()); if (dialog.exec() == QDialog::Rejected) return; std::vector<int> grays(width * height, 0); int countX = dialog.gridX(); int countY = dialog.gridY(); double shiftY = ( (double) height ) / countY; double shiftX = ( (double) width ) / countX; double curX = 0.0; double curY = 0.0; double nextX = 0.0; double nextY = 0.0; int cX; int cY; int nX; int nY; QRgb black = qRgb(0,0,0); QRgb white = qRgb(255,255,255); QRgb newColor; for (int i = 0; i < countY; ++i) { nextY += shiftY; cY = qFloor(curY); nY = qFloor(nextY); curX = 0.0; nextX = 0.0; for (int j = 0; j < countX; ++j) { nextX += shiftX; cX = qFloor(curX); nX = qFloor(nextX); int threshold = otsu(image, grays, cX, cY, nX, nY); for (int y = cY; y < nY; ++y) for (int x = cX; x < nX; ++x) { int gray = grays[x + y * (nX - cX)]; if ( gray < threshold ) newColor = black; else newColor = white; image.setPixel(x, y, newColor); } curX = nextX; } curY = nextY; } pixmap.convertFromImage(image); pixmapItem_2->setPixmap(pixmap); scene_2->setSceneRect(QRectF(pixmap.rect())); calcHist(pixmap, hist_2, maxLevel_2); drawHist(pixmapItem_4, hist_2, maxLevel_2); }
/* Sensible Values for parameter: int gridSize=20; //must be divideable by 2 int globalMaxThreshold=255; int globalMinThreshold=50; //30; */ int OtsuThresholdingWithParameter(densityDataType data, ucharDataType target, int globalMinThreshold, int globalMaxThreshold, int gridSize) { unsigned char *image= (unsigned char *) malloc (data.sizeX*data.sizeY*sizeof (unsigned char)); int rows=data.sizeY; int cols=data.sizeX; int x0=1; int y0=1; int dx=12; int dy=12; int vvv=0;// No out put exept of errors int z; for (z=0;z<data.sizeX*data.sizeY;z++) image[z]=(unsigned char) ( (float) 255.0 * data.data[z]); /* int gridSize=20; //must be divideable by 2 int globalMaxThreshold=255; int globalMinThreshold=50; //30; */ int gridX=data.sizeX/gridSize+1; int gridY=data.sizeY/gridSize+1; unsigned char *thresholdValues= (unsigned char*) malloc (sizeof(unsigned char)*gridX*gridY); unsigned char thresholdResult; int gY, gX; for(gY=1;gY<(gridY-1);gY++) //starts at 1 befor no full element before, stops 1 before because no full elment out there for (gX=1;gX<(gridX-1);gX++) { x0=gX*gridSize-gridSize/2;//move mid point y0=gY*gridSize-gridSize/2; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+gY*gridX]= thresholdResult; }; //The boundary threshold has to be calcultaed different for(gY=1;gY<(gridY-1);gY++) //Boundary is maxium threshold { gX=gridX-1; x0=gX*gridSize-gridSize;//move mid point y0=gY*gridSize-gridSize/2; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[(gridX-1)+gY*gridX]= thresholdResult; }; for(gY=1;gY<(gridY-1);gY++) //Boundary is maxium threshold { gX=0; x0=gX*gridSize;//move mid point y0=gY*gridSize-gridSize/2; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[0+gY*gridX]= thresholdResult; }; for (gX=1;gX<(gridX-1);gX++) //Boundary is maxium threshold { gY=0; x0=gX*gridSize-gridSize/2; /*move mid point*/ y0=gY*gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+0*gridX]= thresholdResult; }; for (gX=1;gX<(gridX-1);gX++) //Boundary is maxium threshold { gY=gridY-1; x0=gX*gridSize-gridSize/2; /*move mid point*/ y0=gY*gridSize-gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+(gridY-1)*gridX]= thresholdResult; }; //The four corners in a other way //Corner1 gX=0; gY=0; x0=gX*gridSize; /*move mid point*/ y0=gY*gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+gY*gridX]= thresholdResult; //Corner2 gX=gridX-1; gY=0; x0=gX*gridSize-gridSize; /*move mid point*/ y0=gY*gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+gY*gridX]= thresholdResult; //Corner3 gX=0; gY=gridY-1; x0=gX*gridSize; /*move mid point*/ y0=gY*gridSize-gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+gY*gridX]= thresholdResult; //Corner4 gX=gridX-1; gY=gridY-1; x0=gX*gridSize-gridSize; /*move mid point*/ y0=gY*gridSize-gridSize; dx=gridSize; dy=gridSize; thresholdResult=(unsigned char) otsu (image, rows, cols, x0, y0, dx, dy, vvv); if (thresholdResult>globalMaxThreshold) thresholdResult=globalMaxThreshold; if (thresholdResult<globalMinThreshold) thresholdResult=globalMinThreshold; thresholdValues[gX+gY*gridX]= thresholdResult; //Elementwise Interpolation for( gY=0;gY<(gridY-1);gY++) for ( gX=0;gX<(gridX-1);gX++) { x0=gX*gridSize; y0=gY*gridSize; int Node1=thresholdValues[gX+gY*gridX]; int Node2=thresholdValues[(gX+1)+gY*gridX]; int Node3=thresholdValues[gX+(gY+1)*gridX]; int Node4=thresholdValues[(gX+1)+(gY+1)*gridX]; int x,y; for (y=0;y<gridSize;y++) for (x=0;x<gridSize;x++) { float psi=(float) x/gridSize; float mu=(float) y/gridSize; float thresholdResult=(float) phi1(psi,mu)*Node1+phi2(psi,mu)*Node2+phi3(psi,mu)*Node3+phi4(psi,mu)*Node4; //printf("x:%d y:%d\n",x,y); if (image[(x+x0)+(y+y0)*data.sizeX]>thresholdResult) { SetBinaryDataAtPoint(target,(x+x0),(y+y0),1); } else { SetBinaryDataAtPoint(target,(x+x0),(y+y0),0); }; }; }; return 0; }
void MainWindow::otsuThresh() { Histogram hist(image); histogram = hist.getImage(); image = otsu(image,hist); setImages(); }
int main(int argc, char **argv) { int thresholdValue = 1; unsigned char image_value[51] = {88,96 , 88 , 80 , 64 , 40 , 8 , 0 , 0 , 0 , 16 , 48 , 72, 88 , 96 , 96 ,96, 96,88 , 96 ,88 ,88 ,80 , 64 , 32 , 0 , 0 , 0 , 0 , 24 , 56 , 80 ,88 ,96, 96 , 96 , 96 , 88 , 96 , 88, 88, 80, 64, 24, 0 , 0 , 0 , 0 , 32, 64, 88}; thresholdValue = otsu(image_value,3,17,0,0,17,3); while(1); }