Ejemplo n.º 1
0
double CheckPatterns::countBlackWhiteTransisitionHorizontal(const ImageGray &sourceImage, int percentage)
{
	//bt->reset();
	//bt->start();

	//int y = (int)(sourceImage.height() / 100.0 * percentage);
	int y = Extensions::getValueFromPercentage(sourceImage.height(), percentage);
	int pixelCounter = 0;
	// set oldpixel to 1 because white is 1 and every ImageGray starts with white
	int oldPixel = 1;

	auto end_ptr = sourceImage.data(0, y + 1);

	bool oldpixel = 1;

	for (auto pxl_ptr = sourceImage.data(0, y); pxl_ptr < end_ptr; pxl_ptr++) {
		bool currentPixel = (*pxl_ptr > thresholdValue);

		pixelCounter += (int)(currentPixel != oldPixel);
		oldPixel = currentPixel;
	}

	//bt->stop();
	//std::cout << "Time for the checkBlackWhiteTransision function: " << //bt->elapsedMicroSeconds() << " Microseconds (" << //bt->elapsedMilliSeconds() << "ms)" << std::endl;
	//return pixelCounter;
	return Extensions::getWeightFromPercentage(Extensions::getPercentage(pixelCounter, percentage));
}
Ejemplo n.º 2
0
double CheckPatterns::countBlackPixelsPerRowHorizontal(const ImageGray &sourceImage, int percentage)
{
	//bt->reset();
	//bt->start();

	if (percentage > 100)
	{
		percentage = 100;
	}
	else if (percentage < 0)
	{
		percentage = 0;
	}

	//int y = (int)(sourceImage.height() / 100.0 * percentage);
	int y = Extensions::getValueFromPercentage(sourceImage.height(), percentage);
	//int y = Extensions::getPercentage(percentage, sourceImage.height());
	int blackPixels = 0;

	auto end_ptr = sourceImage.data(0, y + 1);

	for (auto pxl_ptr = sourceImage.data(0, y); pxl_ptr < end_ptr; pxl_ptr++) {
		blackPixels += (int)(*pxl_ptr < thresholdValue);
	}

	//bt->stop();
	//std::cout << "Time for the countBlackPixelsPerRowHorizontal function: " << //bt->elapsedMicroSeconds() << " Microseconds (" << //bt->elapsedMilliSeconds() << "ms)" << std::endl;

	//return blackPixels;
	//return (int)(blackPixels / (double)(sourceImage.width()) * 100);
	//std::cout << "blackpixels: " << blackPixels << " sourceImg Width: " << sourceImage.width() << " percentage: " << Extensions::getPercentage(blackPixels, sourceImage.width()) << std::endl;
	return Extensions::getWeightFromPercentage(Extensions::getPercentage(blackPixels, sourceImage.width()));
}
Ejemplo n.º 3
0
int extract_cc_(Pixel p, std::vector<Pixel> &cc, ImageGray<BYTE> &img)
{
    std::stack<Pixel> s;
    BYTE *pColor;
    if (img.pixelInside(p.x, p.y))
        pColor = &img.pixel(p.x, p.y);
    else
        return 0;
    while (*pColor == 0 || !s.empty())
    {
        if (*pColor == 0) {
            cc.push_back(p);
            *pColor = 255;
            s.push(Pixel(p.x+1, p.y));
            s.push(Pixel(p.x-1, p.y));
            s.push(Pixel(p.x, p.y+1));
            s.push(Pixel(p.x, p.y-1));
        }
        p = s.top();
        s.pop();
        if (img.pixelInside(p.x, p.y))
            pColor = &img.pixel(p.x, p.y);
        else
            *pColor = 255;
    }
    return cc.size();
}
Ejemplo n.º 4
0
	ImageGray HistEq(const ImageGray& image)
	{
		std::vector<int> hist = Histogram(image);
		int histSum = 0;
		for (int i = 0; i < 256; ++i)
			histSum += hist[i];

		int accumulateSum = 0;
		std::vector<GrayValue> map(256);
		for (int i = 0; i < 256; ++i)
		{
			accumulateSum += hist[i];
			map[i] = static_cast<GrayValue>(accumulateSum * 255.0 / histSum);
		}

		// create new image and map color
		int width = image.GetWidth();
		int height = image.GetHeight();
		GrayValue* data = new GrayValue[width * height];
		for (int x = 0; x < width; ++x)
		{
			for (int y = 0; y < height; ++y)
			{
				data[y * width + x] = map[image.GetValue(x, y)];
			}
		}
		ImageGray gray(width, height, data);
		delete[] data;
		return gray;
	}
Ejemplo n.º 5
0
	std::vector<int> Histogram(const ImageGray& image)
	{
		int width = image.GetWidth();
		int height = image.GetHeight();
		std::vector<int> hist(256);
		for (int x = 0; x < width; ++x)
		{
			for (int y = 0; y < height; ++y)
			{
				GrayValue v = image.GetValue(x, y);
				hist[v]++;
			}
		}
		return hist;
	}
Ejemplo n.º 6
0
SegmentList WaterShedDecomposer::decompose(ImageColor const & image) const {
   QTime time;
   time.start();

   // original image
   image.save("WS1_original.png");

   // filter image
   time.restart();
   ImageColor filtered = filterGauss(image, radiusGauss->value());
   qDebug("Image filtered in %g seconds", time.restart()/1000.0);
   filtered.save("WS2_filtered.png");

   // calculate gradient magnitude map
   time.restart();
   ImageGray gradientMap = gradientMagnitude(filtered);
   qDebug("Gradient magnitude map calculated in %g seconds", time.restart()/1000.0);
   gradientMap.save("WS3_gradient.png");

   // apply watershed transformation
   time.restart();
   SegmentList segments = watershed(gradientMap, image);
   qDebug("Watershed transformation applied in %g seconds", time.restart()/1000.0);
   qDebug("  Segments: %d", segments.size());
   ImageColor debugOut(image.width(), image.height());
   segments.copyToImageAVG(debugOut);
   debugOut.save("WS4_transformed.png");

   // merge similiar and small segments
   time.restart();
   int oldSegmentsSize;
   do {
      oldSegmentsSize = segments.size();
      mergeSimiliarSegments(segments, epsilonMerge->value()*epsilonMerge->value());
      mergeSmallSegments(segments, minSize->value());
   } while (segments.size() != oldSegmentsSize);
   qDebug("Segments merged in %g seconds", time.restart()/1000.0);
   qDebug("  Segments: %d", segments.size());
   segments.copyToImageAVG(debugOut);
   debugOut.save("WS5_merged.png");

   return segments;
}
Ejemplo n.º 7
0
int CheckPatterns::findLeftBlackPixel(const ImageGray &sourceImage)
{
	int xValue = sourceImage.width();
	for (int y = sourceImage.height(); y >= 0; y--)
	{
		for (int x = 0; x <= (sourceImage.width() / 2); x++)
		{
			if (*(sourceImage.data(x, y)) < thresholdValue)
			{
				if (x <= xValue){
					xValue = x;
					x = 0;
					y--;
				}
			}
		}
	}
	return xValue;
}
Ejemplo n.º 8
0
int CheckPatterns::findBottomBlackPixel(const ImageGray &sourceImage)
{
	int yValue = 0;
	for (int x = sourceImage.width(); x >= 0; x--)
	{
		for (int y = sourceImage.height(); y >= (sourceImage.height() / 2); y--)
		{
			if (*(sourceImage.data(x, y)) < thresholdValue)
			{
				if (y >= yValue)
				{
					yValue = y;
					x--;
					y = 0;
				}
			}
		}
	}
	return yValue;
};
Ejemplo n.º 9
0
void extract_CCStats(std::vector<Pixel> &cc, CCStats &stats, const ImageGray<BYTE> &img)
{
    stats.nPoints = cc.size();
    stats.perimeter = 0;
    double meanX = 0, meanY = 0;
    double minX = img.xsize(), minY = img.ysize(), maxX = 0, maxY = 0;
    for (int i = 0; i < cc.size(); i++) {
        meanX += cc[i].x;
        meanY += cc[i].y;
        if (cc[i].x > maxX) maxX = cc[i].x;
        if (cc[i].x < minX) minX = cc[i].x;
        if (cc[i].y > maxY) maxY = cc[i].y;
        if (cc[i].y < minY) minY = cc[i].y;
        stats.perimeter += white_neighbors(Pixel(cc[i].x, cc[i].y), img);
    }
    stats.centerX = meanX / cc.size();
    stats.centerY = meanY / cc.size();
    stats.radius1 = 0.5 * (maxX - minX);
    stats.radius2 = 0.5 * (maxY - minY);
}
Ejemplo n.º 10
0
double CheckPatterns::percentageBlack(const ImageGray & sourceImage, int xleft, int ytop, int xright, int ybottom)
{
	std::pair<int, int> topleft = {
		Extensions::getValueFromPercentage(sourceImage.width(), xleft),
		Extensions::getValueFromPercentage(sourceImage.height(), ytop),
	};

	std::pair<int, int> bottomright = {
		Extensions::getValueFromPercentage(sourceImage.width(), xright),
		Extensions::getValueFromPercentage(sourceImage.height(), ybottom),
	};

	std::pair<int, int> size = {
		bottomright.first - topleft.first,
		bottomright.second - topleft.second
	};

	unsigned int numBlack = 0;

	auto pxl_ptr = sourceImage.data(topleft.first, topleft.second);

	for (int y = size.second; y > 0; --y) {
		for (int x = size.first; x > 0; --x) {
			numBlack += *pxl_ptr < thresholdValue;
			pxl_ptr++;
		}
		pxl_ptr = sourceImage.data(topleft.first, topleft.second + y);
	}

	return Extensions::getWeightFromPercentage(Extensions::getPercentage(numBlack, size.first * size.second));
}
Ejemplo n.º 11
0
double CheckPatterns::firstEdgeLocationLeft(const ImageGray & sourceImage, int percentage)
{
	int y = Extensions::getValueFromPercentage(sourceImage.height(), percentage);
	// set oldpixel to 1 because white is 1 and every ImageGray starts with white
	auto end_ptr = sourceImage.data(sourceImage.width(), y);

	bool oldpixel = 1;
	int x = 0;

	for (auto pxl_ptr = sourceImage.data(0, y); pxl_ptr < end_ptr; pxl_ptr++) {
		bool currentPixel = (*pxl_ptr > thresholdValue);

		if (oldpixel != currentPixel) {
			return Extensions::getWeightFromPercentage(Extensions::getPercentage(x, sourceImage.width()));
		}
		
		oldpixel = currentPixel;
		x++;
	}

	return 1.0;
}
Ejemplo n.º 12
0
double CheckPatterns::checkSymmetryVertical(const ImageGray &sourceImage, bool boundingBox)
{
	//bt->reset();
	//bt->start();
	int numberOfBlackPixels = 0, symmetricBlackPixels = 0;
	//double percentageSymmetric;
	if (boundingBox)
	{
		int x1 = this->findLeftBlackPixel(sourceImage);
		int x2 = this->findRightBlackPixel(sourceImage);
		int y1 = this->findTopBlackPixel(sourceImage);
		int y2 = this->findBottomBlackPixel(sourceImage);
		for (int y = y2; y >= ((y2 - y1) / 2); y--)
		{
			for (int x = x2; x >= x1; x--)
			{
				if (*(sourceImage.data(x, y)) < thresholdValue)
				{
					numberOfBlackPixels++;
					if (*(sourceImage.data(x, sourceImage.height() - y)) < thresholdValue)
					{
						symmetricBlackPixels++;
					}
				}
			}
		}
	}
	else
	{
		for (int x = 0; x < sourceImage.width(); x++)
		{
			auto top_ptr = sourceImage.data(x, 0);

			for (int offset = sourceImage.height() - 1; offset > 0; offset -= 2)
			{
				bool topBlack = *top_ptr < thresholdValue;
				bool bottomBlack = *(top_ptr + offset) < thresholdValue;
				//numberOfBlackPixels += topBlack;
				bool bothBlack = topBlack == bottomBlack;
				symmetricBlackPixels += (int)bothBlack;

				top_ptr += sourceImage.width();
			}
		}
	}
	//percentageSymmetric = ((double)symmetricBlackPixels / (double)numberOfBlackPixels)*100.0;
	//bt->stop();
	//std::cout << "Time for the checkSymmetryVertical function: " << //bt->elapsedMicroSeconds() << " Microseconds (" << //bt->elapsedMilliSeconds() << "ms)" << std::endl;
	//return (int)percentageSymmetric;
	return Extensions::getWeightFromPercentage(Extensions::getPercentage(symmetricBlackPixels, sourceImage.size()/2));
}
Ejemplo n.º 13
0
void IOHelper::ReadPGMFile(char* filename, ImageGray& img)
{
    //Read File
    FILE* file = fopen(filename, "rb+");
    assert(file!=NULL);
    assert(fseek(file, 0, SEEK_END)==0);
    U32 length = ftell(file);
    assert(length>0);
    fseek(file, 0, SEEK_SET);
    U8* bufferRead = new U8[length];
    MemoryClear(bufferRead, length);
    U32 len = fread(bufferRead, 1, length, file);
    assert(len==length);
    fclose(file);
    //Read Image
    itr_vision::FormatPGM FormatPGMObj;
    itr_vision::IFormat::ImageInfo imageInfo;
    assert(FormatPGMObj.GetInfo(bufferRead, length, imageInfo)==itr_vision::IFormat::Success);
    img.Allocate(imageInfo.Width, imageInfo.Height);
    assert(FormatPGMObj.ToImage(bufferRead,length,img)==itr_vision::IFormat::Success);
    delete[] bufferRead;
}
Ejemplo n.º 14
0
bool CC(std::vector<CCStats> &ccstats, const ImageGray<BYTE> &imgbi, ImageRGB<BYTE> &imgFeedback)
{
    ImageGray<BYTE> img_copy(imgbi);
    std::vector<Pixel> firstPixels;
    double meansize = 0;
    for (int i = 0; i < imgbi.xsize(); i++) {
        for (int j = 0; j < imgbi.ysize(); j++) {
            std::vector<Pixel> ccC;
            CCStats stats;
            int npix = extract_cc_(Pixel(i, j), ccC, img_copy);
            if (npix > 180) {
                extract_CCStats(ccC, stats, imgbi);
                double compactness = 4*PI*stats.nPoints / (stats.perimeter*stats.perimeter);
                // !!compactness < 1.3 is not a good limit! I changed to 1.5 -Leman
                if (std::min(stats.radius1,
                             stats.radius2) > 8 && compactness < 1.5 && compactness > 0.7) {
                    ccstats.push_back(stats);
                    firstPixels.push_back(Pixel(i, j));
                    meansize += stats.nPoints;
                    // draw Feedback
                    for (int k = 0; k < ccC.size(); ++k) {
                        Pixel p = ccC[k];
                        // black means detected
                        imgFeedback.pixel_R(p.x, p.y) = 0;
                        imgFeedback.pixel_G(p.x, p.y) = 0;
                        imgFeedback.pixel_B(p.x, p.y) = 0;
                    }
                } else {
                    // draw Feedback
                    for (int k = 0; k < ccC.size(); ++k) {
                        Pixel p = ccC[k];
                        // red means it's not a circle
                        imgFeedback.pixel_R(p.x, p.y) = 150;
                        imgFeedback.pixel_G(p.x, p.y) = 0;
                        imgFeedback.pixel_B(p.x, p.y) = 0;
                    }
                }
            } else {
                // draw Feedback
                for (int k = 0; k < ccC.size(); ++k) {
                    Pixel p = ccC[k];
                    // green means it's too small
                    imgFeedback.pixel_R(p.x, p.y) = 0;
                    imgFeedback.pixel_G(p.x, p.y) = 150;
                    imgFeedback.pixel_B(p.x, p.y) = 0;
                }
            }
        }
        double percent = ((double)i / (double)imgbi.xsize())*100;
        if (!(i % (int)(0.2*imgbi.xsize()+1)))
            libMsg::cout<<(int)(percent+1)<<'%'<<libMsg::flush;
        else if (!(i % (int)(0.04*imgbi.xsize()+1)))
            libMsg::cout<<'.'<<libMsg::flush;
    }
    libMsg::cout<<libMsg::endl;

    if (ccstats.size() == 0) {
        libMsg::cout<<"Nothing interesting found in this image. Please check.";
        return false;
    }
    // retrieve min_size and max_size to build a size histogram
    int max_val = 0;
    int rad_thre = 7;
    for (int i = 0; i < ccstats.size(); i++) {
        if (ccstats[i].nPoints > max_val)
            max_val = ccstats[i].nPoints;
    }

    std::vector<int> hist(max_val);
    std::vector<std::stack<int> > hist_stack(max_val); // to keep indeces of all the circles for given size
    // run through all the sizes and build frequency histogram
    for (int i = 0; i < ccstats.size(); i++) {
        int val = ccstats[i].nPoints-1;
        hist[val]++;
        hist_stack[val].push(i);
    }

    meansize /= ccstats.size();
    int commonsize = meansize;
    libMsg::cout<<"Average area of region: "<<meansize<<" pixels"<<libMsg::endl;
    libMsg::cout<<"Max area of region: "<<max_val<<" pixels"<<libMsg::endl;
    libMsg::cout<<"Region found before filter: [ "<<ccstats.size()<<" ]"<<libMsg::endl;
    /*
     *  frequency
     *   ^
     *   |
     *   |
     *   |               |
     *   |               | |           larger than zerogap
     *   |               | |           so we ignore A and B
     *   |   <--->  | ||||| |   |    <--------------->
     *   |  A     | | ||||| ||  |   |                 B
     *   ----------------------------------------------------> size
     *   0               ^                                10000
     *                   |
     *              average size
     *   negative   <---- ---->  positive
     *   direction               direction
     */
    // collect the inliers in positive direction from commonsize idx

    int zerosgap = meansize/5;
    int count = 0;
    int flag = zerosgap;
    std::vector<int> inliers(ccstats.size());
    while (flag != 0 && commonsize+count < hist.size()) {
        int hist_idx = commonsize + count;
        int onesizecircles = hist[hist_idx];
        if (onesizecircles == 0) {
            flag--;
        } else {
            while (!hist_stack[hist_idx].empty()) {
                inliers[hist_stack[hist_idx].top()] = 1;
                // inliers.push(hist_stack[hist_idx].top());
                hist_stack[hist_idx].pop();
            }
            flag = zerosgap;
        }
        count++;
    }

    // collect the inliers in negative direction from commonsize idx
    count = -1;
    flag = zerosgap;
    while (flag != 0 && commonsize+count >= 0) {
        int hist_idx = commonsize + count;
        int onesizecircles = hist[hist_idx];
        if (onesizecircles == 0) {
            flag--;
        } else {
            while (!hist_stack[hist_idx].empty()) {
                inliers[hist_stack[hist_idx].top()] = 1;
                hist_stack[hist_idx].pop();
            }
            flag = zerosgap;
        }
        count--;
    }

    std::vector<CCStats> erasedCCStats;
    std::vector<int> outliersIdx;
    int idx = 0;
    while (idx < ccstats.size()) {
        if (inliers[idx] == 0) {
            erasedCCStats.push_back(ccstats[idx]);
            outliersIdx.push_back(idx);
            ccstats.erase(ccstats.begin() + idx);
            inliers.erase(inliers.begin() + idx);
        } else {
            idx++;
        }
    }
    libMsg::cout<<"Region found after filter: [ "<<ccstats.size()<<" ]"<<libMsg::endl;
    if (erasedCCStats.size() > 0) {
        libMsg::cout<<"Erased circles:"<<libMsg::endl;
        ImageGray<BYTE> img_copy2(imgbi);
        for (int i = 0; i < erasedCCStats.size(); ++i) {
            CCStats &stats = erasedCCStats[i];
            libMsg::cout<<"circle "<<i<<libMsg::endl;
            libMsg::cout<<"\tarea: "<<stats.nPoints<<libMsg::endl;
            libMsg::cout<<"\tcenter: "<<stats.centerX<<", "<<stats.centerY<<libMsg::endl;
            int index = outliersIdx[i];
            Pixel first = firstPixels[index];
            std::vector<Pixel> ccC;
            extract_cc_(first, ccC, img_copy2);
            for (int k = 0; k < ccC.size(); ++k) {
                Pixel p = ccC[k];
                // blue means filtered
                imgFeedback.pixel_R(p.x, p.y) = 0;
                imgFeedback.pixel_G(p.x, p.y) = 0;
                imgFeedback.pixel_B(p.x, p.y) = 150;
            }
        }
    }
    return true;
}
Ejemplo n.º 15
0
int white_neighbors(const Pixel &p, const ImageGray<BYTE> &img)
{
    int nn = 0;
    Pixel p1(p.x-1, p.y);
    if (p1.x >= 0 && p1.x < img.xsize() && p1.y >= 0 && p1.y < img.ysize()) {
        if (img.pixel(p1.x, p1.y) == 255)
            nn++;
    } else {
        nn++;
    }

    Pixel p2(p.x+1, p.y);
    if (p2.x >= 0 && p2.x < img.xsize() && p2.y >= 0 && p2.y < img.ysize()) {
        if (img.pixel(p2.x, p2.y) == 255)
            nn++;
    } else {
        nn++;
    }

    Pixel p3(p.x, p.y-1);
    if (p3.x >= 0 && p3.x < img.xsize() && p3.y >= 0 && p3.y < img.ysize()) {
        if (img.pixel(p3.x, p3.y) == 255)
            nn++;
    } else {
        nn++;
    }

    Pixel p4(p.x, p.y+1);
    if (p4.x >= 0 && p4.x < img.xsize() && p4.y >= 0 && p4.y < img.ysize()) {
        if (img.pixel(p4.x, p4.y) == 255)
            nn++;
    } else {
        nn++;
    }

    if (nn > 0) nn = 1;
    return nn;
}
Ejemplo n.º 16
0
	void saveImg(const ImageGray & img, const std::string filename)
	{
		CImg<unsigned char> cimg(img.data(), img.width(), img.height(), 1, 1);

		cimg.save(filename.c_str());
	}
Ejemplo n.º 17
0
SegmentList WaterShedDecomposer::watershed(ImageGray const & gradient,
                                           ImageColor const & image) const {
   SegmentList segments;
   std::unique_ptr<int[]> labels(new int[image.area()]);
   for (int i=0; i<image.area(); ++i) labels[i] = -1;

   int offsets[]{-image.width(), -1, 1, image.width()};

   QList<GradPixelRef> queue;
   for (int i=0; i<gradient.area(); ++i) {
      queue << GradPixelRef{gradient.at(i).l, i};
   }
   std::sort(queue.begin(), queue.end(), lessThan);

   int label;
   int lastLabel = -1;
   int i, j;
   QList<int> neighLbls;
   Pixel * pixel;
   Segment * segment;
   foreach (GradPixelRef const & gradPix, queue) {
      i = gradPix.index;
      pixel = new Pixel(Position(i%image.width(), i/image.width()), image.at(i));

      // gather neighbours
      neighLbls.clear();
      for (int o=0; o<4; ++o) {
         j = i + offsets[o];
         if (image.areNeighbours(i, j) && labels[j] > -1 && !neighLbls.contains(labels[j])) {
            neighLbls << labels[j];
         }
      }

      // treat pixel according to neighbour count
      switch (neighLbls.size()) {
      case 0: // new marker
         labels[i] = ++lastLabel;
         segment = new Segment();
         segment->addPixel(pixel);
         segments << segment;
         break;
      case 1: // add to basin
         label = neighLbls.first();
         labels[i] = label;
         segments.at(label)->addPixel(pixel);
         break;
      default: // new watershed
         // add pixel the segment of the nearest neighbour in color
         double distMin = std::numeric_limits<double>::max();
         double dist;
         int jMin = 0;
         for (int o=0; o<4; ++o) {
            j = i + offsets[o];
            if (image.areNeighbours(i, j) && labels[j] > -1) {
               dist = (image.at(i)-image.at(j)).magnitudeSquared();
               if (dist < distMin) {
                  distMin = dist;
                  jMin = j;
               }
            }
         }
         labels[i] = labels[jMin];
         segments.at(labels[jMin])->addPixel(pixel);

         // beneighbour the segments
         for (int k=0; k<neighLbls.count()-1; ++k) {
            for (int l=k+1; l<neighLbls.count(); ++l) {
               segments.at(neighLbls.at(k))->addNeighbour(segments.at(neighLbls.at(l)));
               segments.at(neighLbls.at(l))->addNeighbour(segments.at(neighLbls.at(k)));
            }
         }
         break;
      }
   }