Example #1
0
void ONNXImporter::populateNet(Net dstNet)
{
    CV_Assert(model_proto.has_graph());
    opencv_onnx::GraphProto graph_proto = model_proto.graph();
    std::map<std::string, Mat> constBlobs = getGraphTensors(graph_proto);
    // List of internal blobs shapes.
    std::map<std::string, MatShape> outShapes;
    // Add all the inputs shapes. It includes as constant blobs as network's inputs shapes.
    for (int i = 0; i < graph_proto.input_size(); ++i)
    {
        opencv_onnx::ValueInfoProto valueInfoProto = graph_proto.input(i);
        CV_Assert(valueInfoProto.has_type());
        opencv_onnx::TypeProto typeProto = valueInfoProto.type();
        CV_Assert(typeProto.has_tensor_type());
        opencv_onnx::TypeProto::Tensor tensor = typeProto.tensor_type();
        CV_Assert(tensor.has_shape());
        opencv_onnx::TensorShapeProto tensorShape = tensor.shape();

        MatShape inpShape(tensorShape.dim_size());
        for (int j = 0; j < inpShape.size(); ++j)
        {
            inpShape[j] = tensorShape.dim(j).dim_value();
        }
        outShapes[valueInfoProto.name()] = inpShape;
    }

    std::string framework_name;
    if (model_proto.has_producer_name()) {
        framework_name = model_proto.producer_name();
    }

    // create map with network inputs (without const blobs)
    std::map<std::string, LayerInfo> layer_id;
    std::map<std::string, LayerInfo>::iterator layerId;
    std::map<std::string, MatShape>::iterator shapeIt;
    // fill map: push layer name, layer id and output id
    std::vector<String> netInputs;
    for (int j = 0; j < graph_proto.input_size(); j++)
    {
        const std::string& name = graph_proto.input(j).name();
        if (constBlobs.find(name) == constBlobs.end()) {
            netInputs.push_back(name);
            layer_id.insert(std::make_pair(name, LayerInfo(0, netInputs.size() - 1)));
        }
    }
    dstNet.setInputsNames(netInputs);

    int layersSize = graph_proto.node_size();
    LayerParams layerParams;
    opencv_onnx::NodeProto node_proto;

    for(int li = 0; li < layersSize; li++)
    {
        node_proto = graph_proto.node(li);
        layerParams = getLayerParams(node_proto);
        CV_Assert(node_proto.output_size() >= 1);
        layerParams.name = node_proto.output(0);

        std::string layer_type = node_proto.op_type();
        layerParams.type = layer_type;


        if (layer_type == "MaxPool")
        {
            layerParams.type = "Pooling";
            layerParams.set("pool", "MAX");
            layerParams.set("ceil_mode", isCeilMode(layerParams));
        }
        else if (layer_type == "AveragePool")
        {
            layerParams.type = "Pooling";
            layerParams.set("pool", "AVE");
            layerParams.set("ceil_mode", isCeilMode(layerParams));
            layerParams.set("ave_pool_padded_area", framework_name == "pytorch");
        }
        else if (layer_type == "GlobalAveragePool")
        {
            layerParams.type = "Pooling";
            layerParams.set("pool", "AVE");
            layerParams.set("global_pooling", true);
        }
        else if (layer_type == "Add" || layer_type == "Sum")
        {
            if (layer_id.find(node_proto.input(1)) == layer_id.end())
            {
                Mat blob = getBlob(node_proto, constBlobs, 1);
                blob = blob.reshape(1, 1);
                if (blob.total() == 1) {
                    layerParams.type = "Power";
                    layerParams.set("shift", blob.at<float>(0));
                }
                else {
                    layerParams.type = "Scale";
                    layerParams.set("bias_term", true);
                    layerParams.blobs.push_back(blob);
                }
            }
            else {
                layerParams.type = "Eltwise";
            }
        }
        else if (layer_type == "Sub")
        {
            Mat blob = getBlob(node_proto, constBlobs, 1);
            if (blob.total() == 1) {
                layerParams.type = "Power";
                layerParams.set("shift", -blob.at<float>(0));
            }
            else {
                layerParams.type = "Scale";
                layerParams.set("has_bias", true);
                layerParams.blobs.push_back(-1.0f * blob.reshape(1, 1));
            }
        }
        else if (layer_type == "Div")
        {
            Mat blob = getBlob(node_proto, constBlobs, 1);
            CV_Assert_N(blob.type() == CV_32F, blob.total());
            if (blob.total() == 1)
            {
                layerParams.set("scale", 1.0f / blob.at<float>(0));
                layerParams.type = "Power";
            }
            else
            {
                layerParams.type = "Scale";
                divide(1.0, blob, blob);
                layerParams.blobs.push_back(blob);
                layerParams.set("bias_term", false);
            }
        }
        else if (layer_type == "Constant")
        {
            CV_Assert(node_proto.input_size() == 0);
            CV_Assert(layerParams.blobs.size() == 1);
            constBlobs.insert(std::make_pair(layerParams.name, layerParams.blobs[0]));
            continue;
        }
        else if (layer_type == "ImageScaler")
        {
            const float scale = layerParams.has("scale") ? layerParams.get<float>("scale") : 1.0f;
            layerParams.erase("scale");

            if (layerParams.has("bias"))
            {
                layerParams.type = "Scale";
                layerParams.blobs.push_back(
                    Mat(Size(1,  layerParams.get("bias").size()), CV_32FC1, scale));

                layerParams.set("bias_term", true);
                Mat bias(1, layerParams.get("bias").size(), CV_32FC1);
                for (int j = 0; j < bias.total(); j++) {
                    bias.at<float>(0, j) = layerParams.get("bias").getRealValue(j);
                }
                layerParams.blobs.push_back(bias);
                layerParams.erase("bias");
            }
            else {
                layerParams.set("scale", scale);
                layerParams.type = "Power";
            }
        }
        else if (layer_type == "LeakyRelu")
        {
            layerParams.type = "ReLU";
            replaceLayerParam(layerParams, "alpha", "negative_slope");
        }
        else if (layer_type == "LRN")
        {
            replaceLayerParam(layerParams, "size", "local_size");
        }
        else if (layer_type == "BatchNormalization")
        {
            if (node_proto.input_size() != 5)
                CV_Error(Error::StsNotImplemented,
                         "Expected input, scale, bias, mean and var");

            layerParams.type = "BatchNorm";
            replaceLayerParam(layerParams, "epsilon", "eps");
            replaceLayerParam(layerParams, "spatial", "use_global_stats");

            Mat meanData = getBlob(node_proto, constBlobs, 3);
            Mat stdData =  getBlob(node_proto, constBlobs, 4);

            layerParams.blobs.push_back(meanData);
            layerParams.blobs.push_back(stdData);

            if (!node_proto.input(1).empty()) {
                layerParams.set("has_weight", true);
                layerParams.blobs.push_back(getBlob(node_proto, constBlobs, 1));  // weightData
            } else {
                layerParams.set("has_weight", false);
            }

            if (!node_proto.input(2).empty()) {
                layerParams.set("has_bias", true);
                layerParams.blobs.push_back(getBlob(node_proto, constBlobs, 2)); // biasData
            } else {
                layerParams.set("has_bias", false);
            }
        }
        else if (layer_type == "Gemm")
        {
            CV_Assert(node_proto.input_size() >= 2);
            layerParams.type = "InnerProduct";
            Mat weights = getBlob(node_proto, constBlobs, 1);
            int ind_num_out = 0;
            if (layerParams.has("transB") && !layerParams.get<int>("transB")) {
                transpose(weights, weights);
                ind_num_out = 1;
            }
            layerParams.blobs.push_back(weights);

            if (node_proto.input_size() == 3) {
                Mat bias = getBlob(node_proto, constBlobs, 2);
                layerParams.blobs.push_back(bias);
            }

            layerParams.set("num_output", layerParams.blobs[0].size[ind_num_out]);
            layerParams.set("bias_term", node_proto.input_size() == 3);
        }
        else if (layer_type == "MatMul")
        {
            CV_Assert(node_proto.input_size() == 2);
            layerParams.type = "InnerProduct";
            Mat blob = getBlob(node_proto, constBlobs, 1);
            layerParams.blobs.push_back(blob.t());
            layerParams.set("bias_term", false);
            layerParams.set("num_output", layerParams.blobs[0].size[0]);
        }
        else if (layer_type == "Mul")
        {
            CV_Assert(node_proto.input_size() == 2);
            if (layer_id.find(node_proto.input(1)) == layer_id.end()) {
                Mat blob = getBlob(node_proto, constBlobs, 1);
                blob = blob.reshape(1, 1);
                if (blob.total() == 1) {
                    layerParams.set("scale", blob.at<float>(0));
                    layerParams.type = "Power";
                }
                else {
                    layerParams.blobs.push_back(blob);
                    layerParams.type = "Scale";
                }
            }
            else {
                layerParams.type = "Eltwise";
                layerParams.set("operation", "prod");
            }
        }
        else if (layer_type == "Conv")
        {
            CV_Assert(node_proto.input_size() >= 2);
            layerParams.type = "Convolution";
            for (int j = 1; j < node_proto.input_size(); j++) {
                layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j));
            }
            layerParams.set("num_output", layerParams.blobs[0].size[0]);
            layerParams.set("bias_term", node_proto.input_size() == 3);
        }
        else if (layer_type == "ConvTranspose")
        {
            CV_Assert(node_proto.input_size() >= 2);
            layerParams.type = "Deconvolution";
            for (int j = 1; j < node_proto.input_size(); j++) {
                layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j));
            }
            layerParams.set("num_output", layerParams.blobs[0].size[1]);
            layerParams.set("bias_term", node_proto.input_size() == 3);
        }
        else if (layer_type == "Transpose")
        {
            layerParams.type = "Permute";
            replaceLayerParam(layerParams, "perm", "order");
        }
        else if (layer_type == "Unsqueeze")
        {
            CV_Assert(node_proto.input_size() == 1);
            Mat input = getBlob(node_proto, constBlobs, 0);

            DictValue axes = layerParams.get("axes");
            std::vector<int> dims;
            for (int j = 0; j < input.dims; j++) {
                dims.push_back(input.size[j]);
            }
            CV_Assert(axes.getIntValue(axes.size()-1) <= dims.size());
            for (int j = 0; j < axes.size(); j++) {
                dims.insert(dims.begin() + axes.getIntValue(j), 1);
            }

            Mat out = input.reshape(0, dims);
            constBlobs.insert(std::make_pair(layerParams.name, out));
            continue;
        }
        else if (layer_type == "Reshape")
        {
            CV_Assert(node_proto.input_size() == 2 || layerParams.has("shape"));

            if (node_proto.input_size() == 2) {
                Mat blob = getBlob(node_proto, constBlobs, 1);
                CV_Assert(blob.type() == CV_32SC1);

                if (layer_id.find(node_proto.input(0)) == layer_id.end()) {
                    Mat input = getBlob(node_proto, constBlobs, 0);
                    Mat out = input.reshape(0, static_cast<std::vector<int> >(blob));
                    constBlobs.insert(std::make_pair(layerParams.name, out));
                    continue;
                }
                layerParams.set("dim", DictValue::arrayInt<int*>(
                            blob.ptr<int>(), blob.total() ));
            }
            else {
                DictValue shape = layerParams.get("shape");
                std::vector<int> dim;
                for (int j = 0; j < shape.size(); j++) {
                    dim.push_back(shape.getIntValue(j));
                }

                if (layer_id.find(node_proto.input(0)) == layer_id.end()) {
                    Mat input = getBlob(node_proto, constBlobs, 0);
                    Mat out = input.reshape(0, dim);
                    constBlobs.insert(std::make_pair(layerParams.name, out));
                    continue;
                }
                replaceLayerParam(layerParams, "shape", "dim");
            }
        }
        else if (layer_type == "Pad")
        {
            layerParams.type = "Padding";
        }
        else if (layer_type == "Shape")
        {
            CV_Assert(node_proto.input_size() == 1);
            shapeIt = outShapes.find(node_proto.input(0));
            CV_Assert(shapeIt != outShapes.end());
            MatShape inpShape = shapeIt->second;

            Mat shapeMat(inpShape.size(), 1, CV_32S);
            for (int j = 0; j < inpShape.size(); ++j)
                shapeMat.at<int>(j) = inpShape[j];
            shapeMat.dims = 1;

            constBlobs.insert(std::make_pair(layerParams.name, shapeMat));
            continue;
        }
        else if (layer_type == "Gather")
        {
            CV_Assert(node_proto.input_size() == 2);
            CV_Assert(layerParams.has("axis"));
            Mat input = getBlob(node_proto, constBlobs, 0);
            Mat indexMat = getBlob(node_proto, constBlobs, 1);
            CV_Assert_N(indexMat.type() == CV_32S, indexMat.total() == 1);
            int index = indexMat.at<int>(0);
            int axis = layerParams.get<int>("axis");

            std::vector<cv::Range> ranges(input.dims, Range::all());
            ranges[axis] = Range(index, index + 1);

            Mat out = input(ranges);
            constBlobs.insert(std::make_pair(layerParams.name, out));
            continue;
        }
        else if (layer_type == "Concat")
        {
            bool hasVariableInps = false;
            for (int i = 0; i < node_proto.input_size(); ++i)
            {
                if (layer_id.find(node_proto.input(i)) != layer_id.end())
                {
                    hasVariableInps = true;
                    break;
                }
            }

            if (!hasVariableInps)
            {
                std::vector<Mat> inputs(node_proto.input_size()), concatenated;
                for (size_t i = 0; i < inputs.size(); ++i)
                {
                    inputs[i] = getBlob(node_proto, constBlobs, i);
                }
                Ptr<Layer> concat = ConcatLayer::create(layerParams);
                runLayer(concat, inputs, concatenated);

                CV_Assert(concatenated.size() == 1);
                constBlobs.insert(std::make_pair(layerParams.name, concatenated[0]));
                continue;
            }
        }
        else
        {
            for (int j = 0; j < node_proto.input_size(); j++) {
                if (layer_id.find(node_proto.input(j)) == layer_id.end())
                    layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j));
            }
         }

         int id = dstNet.addLayer(layerParams.name, layerParams.type, layerParams);
         layer_id.insert(std::make_pair(layerParams.name, LayerInfo(id, 0)));


         std::vector<MatShape> layerInpShapes, layerOutShapes, layerInternalShapes;
         for (int j = 0; j < node_proto.input_size(); j++) {
             layerId = layer_id.find(node_proto.input(j));
             if (layerId != layer_id.end()) {
                 dstNet.connect(layerId->second.layerId, layerId->second.outputId, id, j);
                 // Collect input shapes.
                 shapeIt = outShapes.find(node_proto.input(j));
                 CV_Assert(shapeIt != outShapes.end());
                 layerInpShapes.push_back(shapeIt->second);
             }
         }

         // Compute shape of output blob for this layer.
         Ptr<Layer> layer = dstNet.getLayer(id);
         layer->getMemoryShapes(layerInpShapes, 0, layerOutShapes, layerInternalShapes);
         CV_Assert(!layerOutShapes.empty());
         outShapes[layerParams.name] = layerOutShapes[0];
     }
 }
Example #2
0
	__declspec(dllexport) void ModifyPictureContours(char * inFileName, char * outFileName, bool drawItems, int mode) {
		String filename = string(inFileName);
		Mat originalimg = imread(filename);
		Mat img;
		int chan = originalimg.channels();
		cvtColor(originalimg,img, CV_RGB2GRAY);		// seems to be required, even if .net says only 8bpp
		chan = img.channels();
		//bool chk = CV_MAT_TYPE(img.type)== CV_32SC1;
		try {
			/// Find contours  
			vector<vector<Point> > contours;
			vector<Vec4i> hierarchy;
			RNG rng(12345);
			findContours( img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
			/// Draw contours
			float rows = (float) img.rows;
			float cols = (float) img.cols;
			int nContours = 0;
			// pass 1
			float minDistanceFromCenter = 9999999;	// best blob is the on nearest the center.
			for( int i = 0; i< contours.size(); i++ )	// pass 1 to get blob nearest the center.
			{
				double area = contourArea(contours[i]);
				if (area < 20000) continue;
				if (nContours++ > 100) break;

				Moments mu = moments(contours[i], false);
				Point2f massCenter = Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
				if (pointPolygonTest(contours[i], massCenter, false) < 0) continue;

				float distanceFromCenter = pow(pow(massCenter.y-rows/2,2.0) + pow(massCenter.x-cols/2,2),.5);
				if (distanceFromCenter < minDistanceFromCenter) minDistanceFromCenter = distanceFromCenter;
			}
			for( int i = 0; i< contours.size(); i++ )	// pass 2
			{
				double area = contourArea(contours[i]);
				if (area < 20000) continue;
				if (nContours++ > 100) break;
				Moments mu = moments(contours[i], false);
				Point2f massCenter = Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
				if (pointPolygonTest(contours[i], massCenter, false) < 0) continue;

				// new check
				float distanceFromCenter = pow(pow(massCenter.y-rows/2,2.0) + pow(massCenter.x-cols/2,2),.5);
				if (distanceFromCenter > minDistanceFromCenter * 1.001) continue;

				Scalar color = Scalar( 255,255,255 );
				Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
				drawContours( drawing, contours, i, color, CV_FILLED, 8, hierarchy, 0, Point() );

				Mat contourMat = Mat(contours[i]);
				Point2f center; float radius;
				minEnclosingCircle(contourMat, center, radius);
				radius /= 1.03; // see: http://code.opencv.org/issues/3362
				if (drawItems) {

					// draw artifacts, for debugging only.
					circle( drawing, massCenter, 10, Scalar( 255,0,0), -1, 8, 0 );
					Rect rect = boundingRect(contourMat);
					rectangle( drawing, rect.tl(), rect.br(), Scalar( 0,255,0), 2, 8, 0 );
					RotatedRect rotRect = minAreaRect(contourMat);
				    Point2f rect_points[4]; rotRect.points( rect_points );
				    for( int j = 0; j < 4; j++ )
					    line( drawing, rect_points[j], rect_points[(j+1)%4], Scalar( 255,255,255), 1, 8 );
					circle( drawing, center, (int)radius, Scalar(0,0,255), 2, 8, 0 );
				}
				if (mode == 1)
					imwrite(outFileName, drawing);
				else {
					// draw rotation points
					Mat drawing2 = Mat::zeros( img.size(), CV_8UC3 );
					drawContours( drawing2, contours, i, color, 2, 8, hierarchy, 0, Point() );
					Mat drawing3 = Mat::zeros( img.size(), CV_8UC3 );
					circle(drawing3, center, (int)radius, Scalar(0,0,255), 2, 8, 0 );
					Mat outImg;
					bitwise_and(drawing2, drawing3, outImg);	// get intersection of contour and containing circle.
					cvtColor(outImg, outImg, CV_RGB2GRAY);		// seems to be required, even if .net says only 8bpp

					// interesection will not be a point, might be a cluster of points. so get contours, and mass centers
					//medianBlur(outImg, outImg, 17);
					dilate(outImg, outImg, getStructuringElement(MORPH_ELLIPSE, Size(77, 77)));	// mush together all points so we end up w only 2 mass centers

					findContours( outImg, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
					Mat drawing4 = Mat::zeros( img.size(), CV_8UC3 );
					vector<Point2f> rotationPoints;
					Point2f leftmostPoint;
					int leftmostPointIndex = -1;
					for( int i = 0; i< contours.size(); i++ )
					{
						Moments mu = moments(contours[i], false);
						Point2f massCenter = Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
						rotationPoints.push_back(massCenter);
						if (leftmostPointIndex == -1 || massCenter.x < leftmostPoint.x) {
							leftmostPoint = massCenter;
							leftmostPointIndex = i;
						}
						circle( drawing4, massCenter, 10, Scalar( 255,0,0), -1, 8, 0 );	// mass centers are our points.
					}
					
					if (rotationPoints.size() == 2) {
						float angle = 90;
						if (rotationPoints[0].x != rotationPoints[1].x) {
							angle = atan((rotationPoints[0].y - rotationPoints[1].y)/(rotationPoints[0].x - rotationPoints[1].x));
							angle = 180*angle/3.1415;
						}
						float distance = sqrt(
							pow(rotationPoints[0].x - rotationPoints[1].x, 2) +
							pow(rotationPoints[0].y - rotationPoints[1].y, 2));
						if (distance > 0) {
							float factor = cols/distance;
							Mat r = getRotationMatrix2D(leftmostPoint, angle, 1.0);
							//warpAffine(drawing4, drawing4, r, Size(factor*cols, factor*rows));
							//warpAffine(originalimg, drawing4, r, Size(2*cols, 2*rows));

							// at this point, drawing4 has 2 blue rotation points on a black background. that is fine for mode==2.

							if (mode == 3) {   // resize and rotate original image.

								warpAffine(originalimg, drawing4, r, Size(cols, rows));	

								int height = (int) (((float) rows/(float) cols)*distance);
								int originalHeight = height;
								if (leftmostPoint.y < height/2) 
									height = 2*leftmostPoint.y;
								else if ((rows-leftmostPoint.y) < height/2)
									height = 2*(rows - leftmostPoint.y);

								Rect rect = Rect(leftmostPoint.x, leftmostPoint.y - height/2, distance, height);
								drawing4 = drawing4(rect).clone();
								// at this point we have a brain with dimensions distance*height, rotated correctly.
								// stretch to make it have width=cols. Then we'll pad as needed to preserve the original aspect ratio.
								// note, if (height == originalHeight), then the embedded image already has the right aspect ratio.
								// we also need to put the image at the center (vertically).
								resize(drawing4, drawing4, Size(cols, rows * height/originalHeight)); // now image fills width of original image, aspect ratio of image is correct.

								if (height < originalHeight) {	// pad y to correct aspect ratio as needed.
									Mat paddedImage = Mat::zeros( originalimg.size(), originalimg.type() );
									int padding = (originalHeight - height)/2;
									drawing4.copyTo(paddedImage(Rect(0, padding, drawing4.cols, drawing4.rows)));
									drawing4 = paddedImage;
								}
							}
						}
						//if (distance > 0) {
						//	resize(drawing4, drawing4, Size(), cols/distance, cols/distance);
						//}
					}
					imwrite(outFileName, drawing4);
				}
				break;
			}
		}
		catch (cv::Exception& e) {
				cerr << e.msg << endl;
		}
	}
int drawKeypointsList(
	Mat src,                      //вход (м.б. пустым, но нежелательно)
	Keypoint * points,            //список точек
	Mat dst,                      //выход (в общем случае совпадает со входом)
	int radius,                   //радиус окрестности точки > 0, умолч. = 1
	Scalar color,                 //цвет отрисовки, умолч. = белый
	int flags,                    //два флага 0 и 1, умолч. = 1
	int thickness,                //толщина линии, -1 - закрасить, умолч. = 1
	bool verbose                  //флаг доп. инф. умолч. = false
	)
{
	
	assert( radius > 0 );
	assert( thickness == -1 || thickness > 0 );

	if( points == NULL || points->descriptor == NULL )
	{
		if( verbose )
			cout << ERROR_150_V << endl;
		return 150;
	}

	/*  Тяжелый кусок кода для обработки ситуации, когда входная матрица пуста  */
	if( src.empty() && flags == DRAW_ON_EMPTY_FIELD )
	{
		//ищем максимум для координат центров точек и проверяем, есть ли точки на границах
		bool pts_on_borders = false;
		int max_x = 0;
		int max_y = 0;
		for(Keypoint * it = points->next ; it != NULL; it = it->next)
		{
			if( it->center.x > max_x )
				max_x = it->center.x;
			if( it->center.y > max_y)
				max_y = it->center.y;
			if ( pts_on_borders == false && (it->center.x < radius || it->center.y < radius) )
				pts_on_borders = true;
		}
		if (max_x == 0 || max_y == 0)
		{
			if( verbose )
				cout << ERROR_151_V << endl;
			return 151;
		}
		//генерим пустую матрицу, исходя из найденных координат
		if( pts_on_borders ) 
		{
			dst = Mat( max_y + 3 * radius, max_x + 3 * radius, CV_8U );
			//сдвиг координат точек для случая, когда точки на границах
			for(Keypoint * it = points->next ; it != NULL; it = it->next)
			{	
				it->center.x += radius;
				it->center.y += radius;
			}
		}
		else
			dst = Mat( max_y + 2 * radius, max_x + 2 * radius, CV_8U );
	}
	/*  нормальный случай  */
	if ( flags == DRAW_ON_EMPTY_FIELD )
		dst = Mat(src.rows, src.cols, src.type());

	/* Если с матрицей все в порядке, то рисуем точки  */
	if ( flags == DRAW_ON_OUTIMAGE )
	{
		for( Keypoint * it = points ; it != NULL ; it = it->next ) 
			circle(dst, it->center, radius, color, thickness);

	}
	return 0;
}
void czh_minFilter(Mat &srcImage, Mat & dstImage, int radius)
{
	// 该函数输入一个单通道图像,做最小值滤波,窗口大小 size * size
// 	if ( (srcImage.type() != CV_32FC1) || (srcImage.type() != CV_8UC1))
// 	{
// 		cerr << "输入图像必须为单通道图像.\n";
// 		return;
// 	}
	Mat src;
	srcImage.copyTo(src);
	Mat dst(srcImage.size(), srcImage.type(), Scalar::all(0));
	switch (srcImage.type())
	{
	case CV_8UC1:
	{
		int minValue;
		for (int i = radius; i < src.rows - radius; i++)	// 遍历每个像素
		{
			for (int j = radius; j < src.cols - radius; j++)
			{
				minValue = src.at<uchar>(i, j);
				// 针对每个像素,在一个窗口之中遍历寻找最小值
				for (int windows_rows_number = - radius; windows_rows_number <= radius; windows_rows_number++)
				{
					for (int windows_cols_number = - radius; windows_cols_number <= radius; windows_cols_number++)
					{
						if (src.at<uchar>(i + windows_rows_number, j + windows_cols_number) < minValue)
						{
							minValue = src.at<uchar>(i + windows_rows_number, j + windows_cols_number);
						}
					}
				}
				dst.at<uchar>(i, j) = minValue;
			}
		}
		break;
	}
		
	case CV_32FC1:
	{
		float minValue;
		for (int i = radius; i < src.rows - radius; i++)	// 遍历每个像素
		{
			for (int j = radius; j < src.cols - radius; j++)
			{
				minValue = src.at<float>(i, j);
				// 针对每个像素,在一个窗口之中遍历寻找最小值
				for (int windows_rows_number = -radius; windows_rows_number <= radius; windows_rows_number++)
				{
					for (int windows_cols_number = -radius; windows_cols_number <= radius; windows_cols_number++)
					{
						if (src.at<float>(i + windows_rows_number, j + windows_cols_number) < minValue)
						{
							minValue = src.at<float>(i + windows_rows_number, j + windows_cols_number);
						}
					}
				}
				dst.at<float>(i, j) = minValue;
			}
		}
		break;
	}
	} // switch finishes
	
	dstImage = dst;
}
void circleRANSAC(Mat &image, std::vector<Vec3f> &circles, double canny_threshold, double circle_threshold, int numIterations)
{
	CV_Assert(image.type() == CV_8UC1 || image.type() == CV_8UC3);
	circles.clear();

	// Edge Detection
	Mat edges;
	Canny(image, edges, MAX(canny_threshold/2,1), canny_threshold, 3);

	// Create point set from Canny Output
	std::vector<Point2d> points;
	for(int r = 0; r < edges.rows; r++)
	{
		for(int c = 0; c < edges.cols; c++)
		{
			if(edges.at<unsigned char>(r,c) == 255)
			{
				points.push_back(cv::Point2d(c,r));
			}
		}
	}

	// 4 point objects to hold the random samples
	Point2d pointA;
	Point2d pointB;
	Point2d pointC;
	Point2d pointD;

	// distances between points
	double AB;
	double BC;
	double CA;
	double DC;

	// varibales for line equations y = mx + b
	double m_AB;
	double b_AB;
	double m_BC;
	double b_BC;

	// varibles for line midpoints
	double XmidPoint_AB;
	double YmidPoint_AB;
	double XmidPoint_BC;
	double YmidPoint_BC;

	// variables for perpendicular bisectors
	double m2_AB;
	double m2_BC;
	double b2_AB;
	double b2_BC;

	// RANSAC
	cv::RNG rng;
	int min_point_separation = 10; // change to be relative to image size?
	int colinear_tolerance = 1; // make sure points are not on a line
	int radius_tolerance = 1; // change to be relative to image size?
	int points_threshold = 8; //should always be greater than 4
	//double min_circle_separation = 10; //reject a circle if it is too close to a previously found circle
	//double min_radius = 10.0; //minimum radius for a circle to not be rejected

	int x,y;
	Point2d center;
	double radius;

	// Iterate
	for(int iteration = 0; iteration < numIterations; iteration++)
	{
		//std::cout << "RANSAC iteration: " << iteration << std::endl;

		// get 4 random points
		pointA = points[rng.uniform((int)0, (int)points.size())];
		pointB = points[rng.uniform((int)0, (int)points.size())];
		pointC = points[rng.uniform((int)0, (int)points.size())];
		pointD = points[rng.uniform((int)0, (int)points.size())];

		// calc lines
		AB = norm(pointA - pointB);
		BC = norm(pointB - pointC);
		CA = norm(pointC - pointA);
		DC = norm(pointD - pointC);

		// one or more random points are too close together
		if(AB < min_point_separation || BC < min_point_separation || CA < min_point_separation || DC < min_point_separation) continue;

		//find line equations for AB and BC
		//AB
		m_AB = (pointB.y - pointA.y) / (pointB.x - pointA.x + 0.000000001); //avoid divide by 0
		b_AB = pointB.y - m_AB*pointB.x;

		//BC
		m_BC = (pointC.y - pointB.y) / (pointC.x - pointB.x + 0.000000001); //avoid divide by 0
		b_BC = pointC.y - m_BC*pointC.x;


		//test colinearity (ie the points are not all on the same line)
		if(abs(pointC.y - (m_AB*pointC.x + b_AB + colinear_tolerance)) < colinear_tolerance) continue;

		//find perpendicular bisector
		//AB
		//midpoint
		XmidPoint_AB = (pointB.x + pointA.x) / 2.0;
		YmidPoint_AB = m_AB * XmidPoint_AB + b_AB;
		//perpendicular slope
		m2_AB = -1.0 / m_AB;
		//find b2
		b2_AB = YmidPoint_AB - m2_AB*XmidPoint_AB;

		//BC
		//midpoint
		XmidPoint_BC = (pointC.x + pointB.x) / 2.0;
		YmidPoint_BC = m_BC * XmidPoint_BC + b_BC;
		//perpendicular slope
		m2_BC = -1.0 / m_BC;
		//find b2
		b2_BC = YmidPoint_BC - m2_BC*XmidPoint_BC;

		//find intersection = circle center
		x = (b2_AB - b2_BC) / (m2_BC - m2_AB);
		y = m2_AB * x + b2_AB;
		center = Point2d(x,y);
		radius = cv::norm(center - pointB);
		if(radius<15) continue;

		/// geometry debug image
		if(debug)
		{
			Mat debug_image = edges.clone();
			cvtColor(debug_image, debug_image, CV_GRAY2RGB);

			Scalar pink(255,0,255);
			Scalar blue(255,0,0);
			Scalar green(0,255,0);
			Scalar yellow(0,255,255);
			Scalar red(0,0,255);

			// the 3 points from which the circle is calculated in pink
			circle(debug_image, pointA, 3, pink);
			circle(debug_image, pointB, 3, pink);
			circle(debug_image, pointC, 3, pink);

			// the 2 lines (blue) and the perpendicular bisectors (green)
			line(debug_image,pointA,pointB,blue);
			line(debug_image,pointB,pointC,blue);
			line(debug_image,Point(XmidPoint_AB,YmidPoint_AB),center,green);
			line(debug_image,Point(XmidPoint_BC,YmidPoint_BC),center,green);

			circle(debug_image, center, 3, yellow); // center
			circle(debug_image, center, radius, yellow);// circle

			// 4th point check
			circle(debug_image, pointD, 3, red);

			imshow("ransac debug", debug_image);
			waitKey(0);
		}

		//check if the 4 point is on the circle
		if(abs(cv::norm(pointD - center) - radius) > radius_tolerance) continue;

		// vote
		std::vector<int> votes;
		std::vector<int> no_votes;
		for(int i = 0; i < (int)points.size(); i++)
		{
			double vote_radius = norm(points[i] - center);

			if(abs(vote_radius - radius) < radius_tolerance)
			{
				votes.push_back(i);
			}
			else
			{
				no_votes.push_back(i);
			}
		}

		// check votes vs circle_threshold
		if( (float)votes.size() / (2.0*CV_PI*radius) >= circle_threshold )
		{
			circles.push_back(Vec3f(x,y,radius));

			// voting debug image
			if(debug)
			{
				Mat debug_image2 = edges.clone();
				cvtColor(debug_image2, debug_image2, CV_GRAY2RGB);

				Scalar yellow(0,255,255);
				Scalar green(0,255,0);

				circle(debug_image2, center, 3, yellow); // center
				circle(debug_image2, center, radius, yellow);// circle

				// draw points that voted
				for(int i = 0; i < (int)votes.size(); i++)
				{
					circle(debug_image2, points[votes[i]], 1, green);
				}

				imshow("ransac debug", debug_image2);
				waitKey(0);
			}

			// remove points from the set so they can't vote on multiple circles
			std::vector<Point2d> new_points;
			for(int i = 0; i < (int)no_votes.size(); i++)
			{
				new_points.push_back(points[no_votes[i]]);
			}
			points.clear();
			points = new_points;
		}

		// stop RANSAC if there are few points left
		if((int)points.size() < points_threshold)
			break;
	}

	return;
}
Example #6
0
    void run(Mat& image, string& output, vector<Rect>* component_rects=NULL,
             vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
             int component_level=0)
    {

        CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC3) );

#ifdef HAVE_TESSERACT

        if (component_texts != 0)
            component_texts->clear();
        if (component_rects != 0)
            component_rects->clear();
        if (component_confidences != 0)
            component_confidences->clear();

        tess.SetImage((uchar*)image.data, image.size().width, image.size().height, image.channels(), image.step1());
        tess.Recognize(0);
        char *outText;
        outText = tess.GetUTF8Text();
        output = string(outText);
        delete [] outText;

        if ( (component_rects != NULL) || (component_texts != NULL) || (component_confidences != NULL) )
        {
            tesseract::ResultIterator* ri = tess.GetIterator();
            tesseract::PageIteratorLevel level = tesseract::RIL_WORD;
            if (component_level == OCR_LEVEL_TEXTLINE)
                level = tesseract::RIL_TEXTLINE;

            if (ri != 0) {
                do {
                    const char* word = ri->GetUTF8Text(level);
                    if (word == NULL)
                        continue;
                    float conf = ri->Confidence(level);
                    int x1, y1, x2, y2;
                    ri->BoundingBox(level, &x1, &y1, &x2, &y2);

                    if (component_texts != 0)
                        component_texts->push_back(string(word));
                    if (component_rects != 0)
                        component_rects->push_back(Rect(x1,y1,x2-x1,y2-y1));
                    if (component_confidences != 0)
                        component_confidences->push_back(conf);

                    delete[] word;
                } while (ri->Next(level));
            }
            delete ri;
        }

        tess.Clear();

#else

        cout << "OCRTesseract(" << component_level << image.type() <<"): Tesseract not found." << endl;
        output.clear();
        if(component_rects)
            component_rects->clear();
        if(component_texts)
            component_texts->clear();
        if(component_confidences)
            component_confidences->clear();
#endif
    }
void czh_thin_parallel(Mat & srcImage, Mat & dstImage, int iterations)
{
	// 该函数输入一个二值图像或者灰度图像,输出该图像的骨骼
	if (srcImage.type() != CV_8UC1)
	{
		cerr << "只能处理二值或灰度图像.\n";
		cerr << "读取图像函数: imread() 加上参数 \"0\" 或许可以修复该问题.\n";
		return;
	}

	Mat tmpImage;
	int p2, p3, p4, p5, p6, p7, p8, p9;
	uchar * ptrTop, *ptrCur, *ptrBot; // 8邻域中上一行,当前行和下一行的行指针
	// 因为是 8 邻域操作,所以宽和高各减1,防止指针溢出
	const int height = srcImage.rows - 1;	
	const int width = srcImage.cols - 1;
	bool isFinished = false;

	srcImage.copyTo(dstImage);

	for (int it = 0; it < iterations; it++)
	{
		// 每次迭代,都考察 tmpImage 上的点,修改 dstImage 上的数据
		// 新一次的迭代开始时,将 dstImage 上的数据复制到 tmpImage上
		dstImage.copyTo(tmpImage);
		isFinished = false;

		// 遍历扫描过程一:开始
		for (int i = 1; i < height; i++)
		{
			// 给3*3邻域中每一行行指针赋值
			ptrTop = tmpImage.ptr<uchar>(i - 1);
			ptrCur = tmpImage.ptr<uchar>(i);
			ptrBot = tmpImage.ptr<uchar>(i + 1);

			for (int j = 1; j < width; j++)	
			{	
				if (ptrCur[j] > 0)	// 如果当前像素为目标像素的话
				{
					int AP = 0;
					p2 = (ptrTop[j] > 0);
					p3 = (ptrTop[j + 1] > 0);
					p4 = (ptrCur[j + 1] > 0);
					p5 = (ptrBot[j + 1] > 0);
					p6 = (ptrBot[j] > 0);
					p7 = (ptrBot[j - 1] > 0);
					p8 = (ptrCur[j - 1] > 0);
					p9 = (ptrTop[j - 1] > 0);
					if (p2 == 0 && p3 == 1) AP++;
					if (p3 == 0 && p4 == 1) AP++;
					if (p4 == 0 && p5 == 1) AP++;
					if (p5 == 0 && p6 == 1) AP++;
					if (p6 == 0 && p7 == 1) AP++;
					if (p7 == 0 && p8 == 1) AP++;
					if (p8 == 0 && p9 == 1) AP++;
					if (p9 == 0 && p2 == 1) AP++;

					// 如果四个条件都满足的话,则删除 dstImage 中当前点
					if (((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2) && ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6))
					{
						if (AP == 1)
						{
							if (p2*p4*p6 == 0)
							{
								if (p4*p6*p8 == 0)
								{
									dstImage.ptr<uchar>(i)[j] = 0;
									isFinished = true;
								}
							}
						}
					}
				}
			}
		} // 遍历扫描过程一:结束

		  // 遍历扫描过程二:开始
		dstImage.copyTo(tmpImage);
		for (int i = 1; i < height; i++)
		{
			ptrTop = tmpImage.ptr<uchar>(i - 1);
			ptrCur = tmpImage.ptr<uchar>(i);
			ptrBot = tmpImage.ptr<uchar>(i + 1);

			for (int j = 1; j < width; j++)
			{
				if (ptrCur[j] > 0)
				{
					int AP = 0;
					p2 = (ptrTop[j] > 0);
					p3 = (ptrTop[j + 1] > 0);
					p4 = (ptrCur[j + 1] > 0);
					p5 = (ptrBot[j + 1] > 0);
					p6 = (ptrBot[j] > 0);
					p7 = (ptrBot[j - 1] > 0);
					p8 = (ptrCur[j - 1] > 0);
					p9 = (ptrTop[j - 1] > 0);
					if (p2 == 0 && p3 == 1) AP++;
					if (p3 == 0 && p4 == 1) AP++;
					if (p4 == 0 && p5 == 1) AP++;
					if (p5 == 0 && p6 == 1) AP++;
					if (p6 == 0 && p7 == 1) AP++;
					if (p7 == 0 && p8 == 1) AP++;
					if (p8 == 0 && p9 == 1) AP++;
					if (p9 == 0 && p2 == 1) AP++;

					if (((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2) && ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6))
					{
						if (AP == 1)
						{
							if (p2*p4*p8 == 0)
							{
								if (p2*p6*p8 == 0)
								{
									dstImage.ptr<uchar>(i)[j] = 0;
									isFinished = true;
								}
							}
						}
					}

				}
			}
		} // 遍历扫描过程二:结束

		//如果两个遍历扫描过程已经没有可以细化的像素了,则退出迭代
		if (!isFinished) break;
	}
}
// Takes a directory full of single char images, and plops them on a big tif files
// Also creates a box file so Tesseract can recognize it
int main( int argc, const char** argv )
{
  string inDir;

  //Check if user specify image to process
  if(argc == 2)
  {
    inDir = argv[1];
  }
  else
  {
    printf("Use:\n\t%s input dir \n",argv[0]);
    return 0;
  }

  if (DirectoryExists(inDir.c_str()) == false)
  {
    printf("Output dir does not exist\n");
    return 0;
  }

  cout << "Usage: " << endl;
  cout << "\tinputdir	-- input dir for benchmark data" << endl;

  if (DirectoryExists(inDir.c_str()))
  {
    const int X_OFFSET = 10;
    const int Y_OFFSET = 10;

    const int PAGE_MARGIN_X = 70;
    const int PAGE_MARGIN_Y = 70;
    const int HORIZONTAL_RESOLUTION = 3500;

    const int TILE_WIDTH = 55;
    const int CHAR_HORIZ_OFFSET = 40;
    const int TILE_HEIGHT = 70;
    const int CHAR_VERT_OFFSET = 48;

    vector<string> files = getFilesInDir(inDir.c_str());

    sort( files.begin(), files.end(), stringCompare );

    int tiles_per_row = ((float) (HORIZONTAL_RESOLUTION - (PAGE_MARGIN_X * 2))) / ((float) TILE_WIDTH);
    int lines = files.size() / (tiles_per_row);
    int vertical_resolution = (lines * TILE_HEIGHT) + (PAGE_MARGIN_Y * 2) ;
    cout << tiles_per_row <<   " : " << vertical_resolution << endl;

    Mat bigTif = Mat::zeros(Size(HORIZONTAL_RESOLUTION, vertical_resolution), CV_8U);
    bitwise_not(bigTif, bigTif);

    stringstream boxFileOut;

    for (int i = 0; i< files.size(); i++)
    {
      int col = i % tiles_per_row;
      int line = i / tiles_per_row;

      int xPos = (col * TILE_WIDTH) + PAGE_MARGIN_X;
      int yPos = (line * TILE_HEIGHT) + PAGE_MARGIN_Y;

      if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
      {
        string fullpath = inDir + "/" + files[i];

        cout << "Processing file: " << (i + 1) << " of " << files.size() << endl;

        char charcode = files[i][0];

        Mat characterImg = imread(fullpath);
        Mat charImgCopy = Mat::zeros(Size(150, 150), characterImg.type());
        bitwise_not(charImgCopy, charImgCopy);

        characterImg.copyTo(charImgCopy(Rect(X_OFFSET, Y_OFFSET, characterImg.cols, characterImg.rows)));
        cvtColor(charImgCopy, charImgCopy, CV_BGR2GRAY);
        bitwise_not(charImgCopy, charImgCopy);

        vector<vector<Point> > contours;

        //imshow("copy", charImgCopy);
        findContours(charImgCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

        Rect tallestRect(0, 0, 0, 0);
        for (int c = 0; c < contours.size(); c++)
        {
          Rect tmpRect = boundingRect(contours[c]);
          if (tmpRect.height > tallestRect.height)
            tallestRect = tmpRect;
        }

        //cout << tallestRect.x << ":" << tallestRect.y << " -- " << tallestRect.width << ":" << tallestRect.height << endl;

        Rect cropRect(0, tallestRect.y - Y_OFFSET, tallestRect.width, tallestRect.height);

        //cout << "Cropped: " << cropRect.x << ":" << cropRect.y << " -- " << cropRect.width << ":" << cropRect.height << endl;
        Mat cropped(characterImg, cropRect);
        cvtColor(cropped, cropped, CV_BGR2GRAY);

        Rect destinationRect(xPos + (CHAR_HORIZ_OFFSET - tallestRect.width), yPos + (CHAR_VERT_OFFSET - tallestRect.height), tallestRect.width, tallestRect.height);

        //cout << "1" << endl;

        cropped.copyTo(bigTif(destinationRect));

        int x1= destinationRect.x - 2;
        int y1 = (vertical_resolution - destinationRect.y - destinationRect.height) - 2;
        int x2 = (destinationRect.x + destinationRect.width) + 2;
        int y2 = (vertical_resolution - destinationRect.y) + 2;
        //0 70 5602 85 5636 0
        boxFileOut << charcode << " " << x1 << " " << y1 << " ";
        boxFileOut << x2 << " " << y2 ;
        boxFileOut << " 0" << endl;

        //rectangle(characterImg, tallestRect, Scalar(0, 255, 0));
        //imshow("characterImg", cropped);

        waitKey(2);
      }
    }

    imwrite("combined.tif", bigTif);
    ofstream boxFile("combined.box", std::ios::out);
    boxFile << boxFileOut.str();
  }
}
Example #9
0
int main() {
    for (int num = 1; num < 13; num++) { //loop for all the pictures
        //if (num != 3) continue;
        char address[40];
        sprintf(address, "/home/behnam/Downloads/Dubaisi/%i.JPG", num);
        Mat img = imread(address);
        //pre-processing
        GaussianBlur( img, img, Size(31, 31), 2, 2 );
        pyrDown(img, img);
        Mat img_clone = img.clone();
        //extract hsv imag to filter the blue parts in order to find the blue squares
        Mat img_hsv = Mat::zeros(img.rows, img.cols, CV_8UC1);
        cvtColor(img, img_hsv, COLOR_BGR2HSV);
        Mat mask = Mat::zeros(img.rows, img.cols, CV_8UC1);
        //color filter the blue squares
        for (int i = 0; i < img.rows; i++) {
            for (int j = 0; j < img.cols; j++) {
                if (img_hsv.at<Vec3b>(i, j)[0] < 140 and img_hsv.at<Vec3b>(i, j)[0] > 50) {
                    mask.at<uchar>(i, j) = 255;
                }
            }
        }
        Mat maskedImage = Mat::zeros(img.size(), img.type());
        add(img, maskedImage, maskedImage, mask);
        //extract basic features from the image.
        shape_feature_extractor sfe(maskedImage);
        vector<Rect> allSquares;
        //loop through bounding rects to find the blue circles
        for (size_t i = 0; i < sfe.size; i++) {
            Rect rect = sfe.bounding_rects[i];
            double ratio = ((double) rect.width) / rect.height;
            double rectagularity = sfe.good_contours_areas[i] / sfe.bounding_rects_areas[i];
            if (ratio > .9 and ratio < 1.1 and rectagularity > .8) {
                rectangle(img_clone, rect, Scalar(255, 100, 200), 8);
                allSquares.push_back(rect);
            }
        }
        //categorizing the blue circles.
        bool stopLoop = false;
        if (allSquares.size() == 0) stopLoop = true;
        Rect mainThree[3];
        vector<Rect> mainThrees[3];
        if (!stopLoop) mainThrees[0].push_back(allSquares[0]);
        for (size_t i = 1; i < allSquares.size(); i++) {
            for (int j = 0; j < 3; j++) {
                if (mainThrees[j].size() == 0) {
                    mainThrees[j].push_back(allSquares[i]);
                    break;
                }
                else {
                    double dist = distSquares(allSquares[i], mainThrees[j][0]);
                    if (dist < 10) {
                        mainThrees[j].push_back(allSquares[i]);
                        break;
                    }
                }
            }
        }
        int maxRectIndex[3];
        double maxArea[3];
        for (int i = 0; i < 3; i++) {
            if (mainThrees[i].size() == 0) {
                stopLoop = true;
                break;
            }
            maxArea[i] = img.rows * img.cols;
            for (size_t j = 0; j < mainThrees[i].size(); j++) {
                if (maxArea[i] > mainThrees[i][j].area()) {
                    maxArea[i] = mainThrees[i][j].area();
                    maxRectIndex[i] = j;
                }
            }
        }
        for (int i = 0; i < 3; i++) {
            mainThree[i] = mainThrees[i][maxRectIndex[i]];
        }
        if (stopLoop) {
            printf("three blue squares not found!\n");
            continue;
        }
        printf("size of all tha squares: %ld", allSquares.size());
        printf("number of rectangles in each category: %ld, %ld, %ld\n", mainThrees[0].size(), mainThrees[1].size(), mainThrees[2].size());
        printf("maximum area rectable indexes: (%d, %f), (%d, %f), (%d, %f)\n", maxRectIndex[0], maxArea[0],
                maxRectIndex[1], maxArea[1], maxRectIndex[2], maxArea[2]);
        //find features of the blue squares:
        printf("blue angles: ");
        int sharpEdglePointIndex = 0;
        for (int i = 0; i < 3; i++) {
            Point pt0 = findCenter(mainThree[i]);
            Point pt1 = findCenter(mainThree[(i + 1) % 3]);
            Point pt2 = findCenter(mainThree[(i + 2) % 3]);
            line(img_clone, pt0, pt1, Scalar(0, 100, 0), 5);
            line(img_clone, pt2, pt1, Scalar(0, 100, 0), 5);
            line(img_clone, pt2, pt0, Scalar(0, 100, 0), 5);
            double angle = findAngle(pt1, pt2, pt0);
            if (angle < 40) {
                sharpEdglePointIndex = i;
            }
            printf("%f, ", angle);
        }
        
        Rect temp = mainThree[sharpEdglePointIndex];
        mainThree[sharpEdglePointIndex] = mainThree[0];
        mainThree[0] = temp;

        printf("sharp point index: %d\n", sharpEdglePointIndex);
        circle(img_clone, findCenter(mainThree[0]), 5, Scalar(50, 0, 0), 5);

        //finding the gray rectangle
        shape_feature_extractor sfe2(img);
        vector<vector<Point>> grayRectangles;
        for (size_t i = 0; i < sfe2.size; i++) {
            Mat roi(img, sfe2.bounding_rects[i]);
            Mat tmplt = imread("/home/behnam/Downloads/Dubaisi/redRectangle.jpg");
            int tmplt_area = tmplt.rows * tmplt.cols;
            //area an histogram analysis
            double histAnalysis = compareHistogram(tmplt, roi, 0);
            RotatedRect rRect = sfe2.min_rects[i];
            Size2f size = rRect.size;
            double sideRatio = size.height / size.width; sideRatio = sideRatio >= 1 ? sideRatio : 1 / sideRatio;
            double area = sfe2.min_rects_areas[i];
            double area_ratio = area / mainThree[0].area();
            double rectangularity = sfe2.good_contours_areas[i] / sfe2.min_rects_areas[i];
            double angleCos = cos(rRect.angle / 180 * M_PI);
            double angle1 = findAngle(findCenter(mainThree[1]), rRect.center, findCenter(mainThree[0]));
            double angle2 = findAngle(findCenter(mainThree[2]), rRect.center, findCenter(mainThree[0]));
            double hull_ratio = utilities::calc_area(sfe2.hulls[i]) / area;
            if ( histAnalysis > .3
                and area_ratio > 1.2 and area_ratio < 2
                and sideRatio < 1.6 and sideRatio > 1.3 
                and angle1 > 10 and angle1 < 27
                and angle2 > 10 and angle2 < 27
                and rectangularity > .6
                //and num_h > 100
                //and num_s > 100
                ) {
                vector<Point> points = utilities::rotatedRect_to_contour(rRect);
                printf("area: %f\n", area);
                printf("area ratio %f\n", area_ratio);
                printf("side ratio: %f\n", sideRatio);
                printf("rectangularity: %f\n", rectangularity);
                printf("angle: %f, %f\n", angle1, angle2);
                printf("hull ratio %f\n", hull_ratio);
                printf("hist analysis: %f\n", histAnalysis);
                printf("****************\n");
                grayRectangles.push_back(points);
            }
        }

        drawContours(img_clone, grayRectangles, -1, Scalar(0, 0, 100), 5);

        imshow("image", img_clone);
        waitKey(0);
        printf("************************************************************************************\n");
    }
}
Example #10
0
void image_info(Mat &img)
{
    std::cout << "Channels: " << img.channels() << std::endl;
    std::cout << "Depth: "  << img.type() << std::endl;
    std::cout << "Size: "  << img.size() << std::endl;
}
void TestAffine()
{
	using namespace cv;
	/*Mat img1 = imread("..//PTZ//input0//in000007.jpg");
	Mat img2 = imread("..//PTZ//input0//in000008.jpg");*/
	Mat img1 = imread("..//PTZ//input3//in000204.jpg");
	Mat img2 = imread("..//PTZ//input3//in000211.jpg");
	Mat gray1,gray2;
	cvtColor(img1, gray1, CV_BGR2GRAY); 
	cvtColor(img2, gray2, CV_BGR2GRAY);
	imwrite("i1.jpg",gray1);
	imwrite("i2.jpg",gray2);
	std::vector<cv::Point2f> features1,features2;  // detected features

	int max_count = 50;	  // maximum number of features to detect
	double qlevel = 0.01;    // quality level for feature detection
	double minDist = 10;   // minimum distance between two feature points
	std::vector<uchar> status; // status of tracked features
	std::vector<float> err;    // error in tracking
	// detect the features
	cv::goodFeaturesToTrack(gray1, // the image 
		features1,   // the output detected features
		max_count,  // the maximum number of features 
		qlevel,     // quality level
		minDist);   // min distance between two features

	// 2. track features
	cv::calcOpticalFlowPyrLK(gray1, gray2, // 2 consecutive images
		features1, // input point position in first image
		features2, // output point postion in the second image
		status,    // tracking success
		err);      // tracking error

	Mat affine = estimateRigidTransform(features1,features2,true);
	Mat result;
	warpAffine(gray1,result,affine,cv::Size(gray1.cols,gray1.rows));
	imwrite("i3.jpg",result);
	std::cout<<"affine"<<std::endl;
	std::cout<<affine;
	Mat A(2,2,affine.type());
	for(int i=0; i<2; i++)
		for(int j=0;j<2;j++)
			A.at<double>(i,j) = affine.at<double>(i,j);
	A = A.inv();
	Mat invAffine(2,3,affine.type());
	for(int i=0; i<2; i++)
		for(int j=0;j<2;j++)
			invAffine.at<double>(i,j) = A.at<double>(i,j);
	invAffine.at<double>(0,2) = affine.at<double>(0,2)*-1;
	invAffine.at<double>(1,2) = affine.at<double>(1,2)*-1;
	Mat grayInv;
	cout<<invAffine;
	warpAffine(result,grayInv,invAffine,cv::Size(grayInv.cols,grayInv.rows));
	imshow("inv affine",grayInv);
	Mat out;
	std::vector<uchar> in(features1.size(),0);
	estimateAffine2D(features1,features2,out,in);
	std::cout<<out;
	Mat rresult;
	warpAffine(gray1,rresult,out,cv::Size(gray1.cols,gray1.rows));

	std::vector<uchar> inliers(features1.size(),0);
	cv::Mat homography= cv::findHomography(
		cv::Mat(features1), // corresponding
		cv::Mat(features2), // points
		inliers, // outputted inliers matches
		CV_RANSAC, // RANSAC method
		1.); // max distance to reprojection point
	
	// Warp image 1 to image 2
	cv::Mat presult;
	cv::warpPerspective(gray1, // input image
		presult,			// output image
		homography,		// homography
		cv::Size(gray1.cols,gray1.rows)); // size of output image

	Mat ErrImg = abs(gray2 - result);
	ErrImg.convertTo(ErrImg,CV_8U);
	Mat pErrImg = abs(gray2 - presult);
	Mat rErrImg = abs(gray2 - rresult);
	// Display the warp image
	cv::namedWindow("After perspective warping");
	cv::imshow("After perspective warping",presult);

	cv::namedWindow("After affine warping");
	cv::imshow("After affine warping",result);

	cv::namedWindow("After ransac affine warping");
	cv::imshow("After ransac affine warping",rresult);

	cv::namedWindow("img1");
	cv::imshow("img1",gray1);
	cv::namedWindow("img2");
	cv::imshow("img2",gray2);

	cv::namedWindow("affine error");

	imwrite("i2-i3.jpg",ErrImg);
	cv::imshow("affine error",ErrImg);
	/*cv::Mat ErrImgRead = imread("i2-i3.bmp");
	cv::imshow("affine error read",ErrImgRead);*/
	cv::namedWindow("ransac affine error");
	cv::imshow("ransac affine error",rErrImg);
	cv::namedWindow("perror");
	cv::imshow("perror",pErrImg);

	cv::waitKey();
}
Example #12
0
int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim )
{
    int srcType = src.type();
    bool support = false;
    if( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
    {
        if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
            support = true;
        if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) )
            support = true;
        if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) )
            support = true;
        if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) )
            support = true;
        if( srcType == CV_64F && dstType == CV_64F)
            support = true;
    }
    else if( opType == CV_REDUCE_MAX )
    {
        if( srcType == CV_8U && dstType == CV_8U )
            support = true;
        if( srcType == CV_32F && dstType == CV_32F )
            support = true;
        if( srcType == CV_64F && dstType == CV_64F )
            support = true;
    }
    else if( opType == CV_REDUCE_MIN )
    {
        if( srcType == CV_8U && dstType == CV_8U)
            support = true;
        if( srcType == CV_32F && dstType == CV_32F)
            support = true;
        if( srcType == CV_64F && dstType == CV_64F)
            support = true;
    }
    if( !support )
        return cvtest::TS::OK;

    double eps = 0.0;
    if ( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
    {
        if ( dstType == CV_32F )
            eps = 1.e-5;
        else if( dstType == CV_64F )
            eps = 1.e-8;
        else if ( dstType == CV_32S )
            eps = 0.6;
    }

    assert( opRes.type() == CV_64FC1 );
    Mat _dst, dst, diff;
    reduce( src, _dst, dim, opType, dstType );
    _dst.convertTo( dst, CV_64FC1 );

    absdiff( opRes,dst,diff );
    bool check = false;
    if (dstType == CV_32F || dstType == CV_64F)
        check = countNonZero(diff>eps*dst) > 0;
    else
        check = countNonZero(diff>eps) > 0;
    if( check )
    {
        char msg[100];
        const char* opTypeStr = opType == CV_REDUCE_SUM ? "CV_REDUCE_SUM" :
        opType == CV_REDUCE_AVG ? "CV_REDUCE_AVG" :
        opType == CV_REDUCE_MAX ? "CV_REDUCE_MAX" :
        opType == CV_REDUCE_MIN ? "CV_REDUCE_MIN" : "unknown operation type";
        string srcTypeStr, dstTypeStr;
        getMatTypeStr( src.type(), srcTypeStr );
        getMatTypeStr( dstType, dstTypeStr );
        const char* dimStr = dim == 0 ? "ROWS" : "COLS";

        sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
                srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
        ts->printf( cvtest::TS::LOG, msg );
        return cvtest::TS::FAIL_BAD_ACCURACY;
    }
    return cvtest::TS::OK;
}
Example #13
0
inline bool Face::extractEyebrows(Mat eyeRegionImg, bool doBluring, Point leb[4], Point reb[4], Point& cleye, Point& creye, Point lefcps [5], Point refcps [5])
{
    // Alias for eyebrows'points (left, right, up, down).
    Point&  lleb = leb[0];
    Point&  rleb = leb[1];
    Point&  uleb = leb[2];
    Point&  dleb = leb[3];
    Point&  lreb = reb[0];
    Point&  rreb = reb[1];
    Point&  ureb = reb[2];
    Point&  dreb = reb[3];


    //We will get the four widest areas of the contours extracted from the Otsu Thresholded image of the Sobel transform of the gaussian blured version (to get rid of foredhead wrinkles, hair, etc) of the original image.
    vector<vector<Point> > contours;
    Rect bigBox1, bigBox2;
    Mat imContours;

    Mat blur, blurSobel, blurSTh;

    eyeRegionImg.copyTo(blur);
    if (doBluring) GaussianBlur( eyeRegionImg , blur, Size(5, 5), 2, 2);

    //Sobel filter. Horizontal, 2nd order, single channel 255 bit-depth, 3x3 kernel.
    Sobel(blur, blurSobel,CV_8UC1, 0, 2 , 3);

    //Thresholding so only hard edges stay.Automatic threshold estimated with Otsu algorithm. Both numbers 255 are ignored (dummy).
    threshold(blurSobel, blurSTh, 255,255, THRESH_BINARY | THRESH_OTSU);
    //adaptiveThreshold(blurSobel, blurSTh,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,/*((eyesSobel.size().width) % 2 == 1? (eyesSobel.size().width) : (eyesSobel.size().width) + 1 )*/ 3,-2);

    blurSTh.copyTo(imContours);

/*
    cv::imshow( "SThEClose", imContours);
    cvMoveWindow("SThEClose", 1200, 300 );

    cv::imshow( "Blur", blur);
    cvMoveWindow("Blur", 1200, 500 );

    cv::imshow( "BlurSobel", blurSobel);
    cvMoveWindow("BlurSobel", 1200, 700 );
*/


    //Dividing eye region in left and right halfs. This made the algorithm more robust to face rotation.
    Rect halfsideBox;
    Mat eyeNeg =  Mat(eyeRegionImg.size(),eyeRegionImg.type(), CV_RGB(255,255,255)) - eyeRegionImg  ;
    for (int iteration = 0; iteration < 2; iteration++)
    {

        //Left half
        if ( iteration == 0 )
        {
            halfsideBox.x = 0;
            halfsideBox.y = 0;
            halfsideBox.width = imContours.size().width * 0.5;
            halfsideBox.height = imContours.size().height;
        }
        else
        {
            halfsideBox.x = std::floor(imContours.size().width * 0.5);
            halfsideBox.y = 0;
            halfsideBox.width = imContours.size().width * 0.5 - 1;
            halfsideBox.height = imContours.size().height;

        }

        Mat halfImContours = imContours(halfsideBox);

        findContours(halfImContours,contours,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

        //Sorting by area and darkness. TODO: improve heuristics to sort by (e.g: use area or width/mean value (max area and darkest)*relative down position)
        const int CAREAS_SZ = 500;
        int cAreasIdx [CAREAS_SZ];
        int cAreas [CAREAS_SZ];
        /*Computing areas and sorting (bubble sort .. improve)*/
        unsigned j;
        for( j = 0 ; j < contours.size() && j < CAREAS_SZ; j++)
        {
            int aux1, aux2, auxIdx1, auxIdx2;
            Mat matcnt (contours[j]);
            Rect bbox = boundingRect(matcnt);

            //Cost funtion to maximize: max(area * darkest)
            double costf = sum(eyeNeg(halfsideBox)(bbox)) [0] ; //Other things tryed: (sum(eyeNeg(halfsideBox))[0]))  + ((bbox.y + (bbox.height/2)) / halfImContours.size().height ; //bbox.area();

            //cout << "Area " << j << ": " << area << endl;

            //Sorting
            int i = 0;
            while (i < j && costf <= cAreas[i]) i++;

            aux1 = costf;
            auxIdx1 = j;
            while (i <= j)
            {
                aux2 = cAreas[i];
                cAreas[i] = aux1;
                aux1 = aux2;

                auxIdx2 = cAreasIdx[i];
                cAreasIdx[i] = auxIdx1;
                auxIdx1 = auxIdx2;

                i++;
            }
        }


        if (contours.size() >= 2) {

            //Position 0 will have the eyebrow and 1 the eye.
            if (boundingRect(contours[cAreasIdx[1]]).y < boundingRect(contours[cAreasIdx[0]]).y)
            {
                int aux = cAreasIdx[0];
                cAreasIdx[0] = cAreasIdx[1];
                cAreasIdx[1] = aux;
            }

            if (iteration == 0)
            {
                findBoundingPoints(contours.at(cAreasIdx[0]),&lleb,&rleb,&uleb, &dleb);
                lleb += halfsideBox.tl();
                rleb += halfsideBox.tl();
                uleb += halfsideBox.tl();
                dleb += halfsideBox.tl();
            }
            else
            {
                findBoundingPoints(contours.at(cAreasIdx[0]),&lreb,&rreb,&ureb, &dreb);
                lreb += halfsideBox.tl();
                rreb += halfsideBox.tl();
                ureb += halfsideBox.tl();
                dreb += halfsideBox.tl();
            }

            //Extracting Eye Center. Considered the darkest point in eye contour. TODO: Try to improve with a geometric centroid of the darkest region.
            Rect eyeBox= boundingRect(Mat(contours[cAreasIdx[1]]));
            Point p1,p2;
            double pv1,pv2;

            minMaxLoc(blur(eyeBox),&pv2, &pv1,&p2, &p1);
            p2.x = p2.x + eyeBox.x;
            p2.y = p2.y + eyeBox.y;

            if (iteration == 0 )
                cleye = p2 + halfsideBox.tl(); // Center of Left Eye
            else
                creye = p2 + halfsideBox.tl(); // Center of Right Eye

            //DEBUG
            for (int i = 0; i < 2 && i < contours.size(); i++ )
            {
                Point laux ;
                Point raux ;
                Point uaux ;
                Point daux ;

                findBoundingPoints(contours[cAreasIdx[i]],&laux,&raux,&uaux, &daux);

                Rect br;
                br.x = laux.x;
                br.y = uaux.y;
                br.width = raux.x - br.x + 1;
                br.height = daux.y - br.y + 1;

                //DEBUG
                Scalar colorR;

                colorR = i >= 1? CV_RGB (120,120,120) : CV_RGB (255,255,255);

                rectangle(eyeNeg, br.tl() + halfsideBox.tl() ,br.br() + halfsideBox.tl(),colorR,1);

            }


            //DEBUG
            //findBoundingPoints(contours.at(cAreasIdx[1]),&lefcps[0],&lefcps[1],&lefcps[2], &lefcps[3]);
            //lefcps[0] += halfsideBox.tl();
            //lefcps[1] += halfsideBox.tl();
            //lefcps[2] += halfsideBox.tl();
            //lefcps[3] += halfsideBox.tl();
            //if (iteration == 0){
            //    debuglefcps = lefcps[3];
            //}
            //line(eyeRegionImg,Point(iteration * eyeRegionImg.size().width/2, lefcps[2].y), Point(eyeRegionImg.size().width/(2-iteration) -1, lefcps[2].y),  CV_RGB (255,255,255), 1);
            //circle (eyeRegionImg, lefcps[2], 0, CV_RGB (255,255,255),-1);
            //line(eyeRegionImg,Point(0, lefcps[3].y), Point(eyeRegionImg.size().width/2 -1, lefcps[3].y),  CV_RGB (255,255,255), 1);
            //circle (eyeRegionImg, lefcps[3], 0, CV_RGB (255,255,255),-1);



        }else
            return false; //Some eyebrow or eye was not found

        //DEBUG
        //cv::imshow( "NegEyes", eyeNeg );
        //cvMoveWindow("NegEyes", 1400, 300 );

    }

    //Finding right eye corners
    Rect ler; //Left Eye Region
    ler.x = 0;
    ler.y = std::max (0, std::min(eyeRegionImg.size().height-1, dleb.y + 1)); //Not including eyebrow point.
    ler.width = std::max(0, int(std::ceil(eyeRegionImg.size().width / 2.0)));
    ler.height = std::max(0, eyeRegionImg.rows - ler.y);

    //Left Eye facial Characteristic Points: left and right corners, up and down eyelids, and center  respectively from 0 to 4.
    if (cleye.y < ler.y) cleye.y = ler.y; //To be sure that eyecenter is in left eye region (ler) and below eyebrow.
    extractEyeCorners (eyeRegionImg(ler), lefcps, cleye - ler.tl());



     //Finding right eye corners
    Rect rer; //Left Eye Region
    rer.x = std::max(0, int(std::ceil(eyeRegionImg.size().width / 2.0)) - 1);
    rer.y = std::max (0, std::min(eyeRegionImg.size().height-1, dreb.y + 1)); //Not including eyebrow point.
    rer.width = std::max(0, eyeRegionImg.size().width - rer.x);
    rer.height = std::max(0, eyeRegionImg.rows - rer.y);

     //Right Eye facial Characteristic Points: left and right corners, up and down eyelids, and center  respectively from 0 to 4.
    if (creye.y < rer.y) creye.y = rer.y; //To be sure that eyecenter is in left eye region (ler) and below eyebrow.
    extractEyeCorners (eyeRegionImg(rer), refcps, creye - rer.tl());


    //Relocating points
    int i=5;
    while (0 < i--)
    {
        lefcps [i] += ler.tl();
        refcps [i] += rer.tl();
    }


/*
    cv::imshow( "EBlur", blured);
    cvMoveWindow("EBlur", 1200, 500 );


    cv::imshow( "SEyes", eyesSobel);
    cvMoveWindow("SEyes", 700, 500 );

    cv::imshow( "ThEyes", eyesTh );
    cvMoveWindow("ThEyes", 700,300);
    cv::imshow( "SThEyes", eyesSTh);
    cvMoveWindow("SThEyes", 1000, 300 );
*/

    return true; //OK
}
Example #14
0
inline bool Face::extractMouthPoints (Mat mouthImg, Point& llips, Point& rlips, Point& ulips, Point& dlips)
{
    Mat mouthImgTh, mouthSobel, kernel(1,5,CV_8UC1,1);

    //Sobel filter. Horizontal, 2nd order, single channel 255 bit-depth, 3x3 kernel.
    Sobel(mouthImg, mouthSobel, CV_8UC1, 0, 2, 3);


    //Thresholding so only hard edges stay.Automatic threshold estimated with Otsu algorithm. Both numbers 255 are ignored (dummy).
    threshold(mouthSobel, mouthImgTh, 255,255, THRESH_BINARY | THRESH_OTSU);

    Mat mouthAdapTh;
    adaptiveThreshold(mouthSobel,mouthAdapTh,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,((mouthSobel.size().width) % 2 == 1? (mouthSobel.size().width) : (mouthSobel.size().width) + 1 ),-15);


    vector<vector<Point> > contours;
    Rect bigBox;
    Mat imContours;

    mouthAdapTh.copyTo(imContours);
    findContours(imContours,contours,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

    int cind;
    for( unsigned  j = 0 ; j < contours.size(); j++)
    {

        Mat matcnt (contours[j]);
        Rect bbox = boundingRect (matcnt);

        if (bbox.width > bigBox.width) {
            // O novo pasa a maior
            bigBox = bbox;
            cind = j;
        }
    }


    if (contours.size()>0)
        Face::findBoundingPoints(contours.at(cind),&llips,&rlips,&ulips, &dlips);
    else
        return false; //The image got totally black. No mouth detected.



    //Finding Upper lip y coordinate. The longest horizontal edge within the brightest.
    //integral(mouthSobel, mouthIntegral);
    Mat mouthEroded;
    erode(mouthAdapTh, mouthEroded, kernel);
    Mat lip2 = mouthEroded(bigBox);
    Mat vPrj (lip2.size().height, 1, CV_32FC1); //One coloumn
    Point p1,p2;
    double pv1,pv2;

    Face::project(lip2, NULL, &vPrj);

    minMaxLoc(vPrj,&pv2, &pv1,&p2, &p1);

    ulips.y = p1.y + bigBox.tl().y;

    //Adjust de upper and lower lip 'x' coordinates to the middle. Otherwise they will be moving with noise.
    ulips.x = int((rlips.x + llips.x)/2);




    /* Detecting Lower Lip (dlip) */
    Mat lipmap;
    Mat mouthComp = Mat(mouthImg.size(),mouthImg.type(), CV_RGB(255,255,255)) - mouthImg  ;
    addWeighted( mouthSobel, 0.5, mouthComp, 0.5, 0, lipmap);
    Mat mouthAdapTh3;
    adaptiveThreshold(lipmap, mouthAdapTh3,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,((mouthSobel.size().width) % 2 == 1? (mouthSobel.size().width) : (mouthSobel.size().width) + 1 ),-10);


    mouthAdapTh3.copyTo(imContours);
    //mouthImgTh.copyTo(imContours);
    findContours(imContours,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);

    //Sorting by area and darkness. TODO: improve heuristics to sort by (e.g: use area or width/mean value (max area and darkest)*relative down position)
    const int CAREAS_SZ = 500;
    int cAreasIdx [CAREAS_SZ];
    int cAreas [CAREAS_SZ];
    /*Computing areas and sorting (bubble sort .. improve)*/
    unsigned j;
    for( j = 0 ; j < contours.size() && j < CAREAS_SZ; j++)
    {
        int aux1, aux2, auxIdx1, auxIdx2;
        Mat matcnt (contours[j]);
        Rect bbox = boundingRect(matcnt);

        //Cost funtion to maximize: max(area * darkest)  // this does not work lowest located in 'y' coordinate
        double costf = bbox.width; //sum(lipmap(bbox)) [0] ;// (sum(eyeNeg(halfsideBox))[0]))  + ((bbox.y + (bbox.height/2)) / halfImContours.size().height ;

        //cout << "Area " << j << ": " << area << endl;

        //Sorting
        int i = 0;
        while (i < j && costf <= cAreas[i]) i++;

        aux1 = costf;
        auxIdx1 = j;
        while (i <= j)
        {
            aux2 = cAreas[i];
            cAreas[i] = aux1;
            aux1 = aux2;

            auxIdx2 = cAreasIdx[i];
            cAreasIdx[i] = auxIdx1;
            auxIdx1 = auxIdx2;

            i++;
        }
    }

    if (contours.size() >= 1) {
        Mat matcnt (contours.at(cAreasIdx[0]));
        bigBox = boundingRect(matcnt);
        Face::findBoundingPoints(contours.at(cAreasIdx[0]),NULL, NULL, NULL, &dlips);
        //Adjust de upper and lower lip 'x' coordinates to the middle. Otherwise they will be moving with noise.
        ulips.x = int((rlips.x + llips.x)/2);
        dlips.x = int((rlips.x + llips.x)/2);

    }

    return true;
}
Example #15
0
void HoughImg( const Mat& img, float rho, float theta, Mat& dst ) {
  int i, j;
  float irho = 1/rho;

  CV_Assert( img.type() == CV_8UC1 );

  const uchar* image = img.ptr();
  int step = (int)img.step;
  int width = img.cols;
  int height = img.rows;


  int numangle = cvRound( CV_PI / 2 / theta );
  int numrho = cvRound(((width+height) * 2 + 1) / rho);

  printf("numangle: %d, numrho: %d\n", numangle, numrho);

//  AutoBuffer<float> _accum((numangle+2) * (numrho+2));

  if (dst.empty()) {
    dst.create((numangle+2),(numrho+2), CV_32F);
  }

  dst = Scalar::all(0.0);

  float* accum = (float *)dst.ptr();
  int astep = dst.step;

  AutoBuffer<float> _tabSin(numangle);
  AutoBuffer<float> _tabCos(numangle);

  float *tabSin = _tabSin, *tabCos = _tabCos;

//  memset( accum, 0, sizeof(accum[0]) * (numangle + 2 ) * (numrho + 2) );
  float ang = 0; //min_theta;
  for(int n=0; n<numangle; ang+=theta, n++) {
    tabSin[n] = (float)(sin((double)ang)) * irho;
    tabCos[n] = (float)(cos((double)ang)) * irho;
  }
  printf("fill..\n");
  //fill accum
  for(i=0;i<height;i++)
    for(j=0;j<width;j++) {
      for (int n=0; n<numangle; n++) {
        int r = cvRound( j * tabCos[n] + i * tabSin[n] );
        r+= (numrho - 1) / 2;
        dst.at<float>(Point((r+1),(n+1))) += (float)(image[i*step+j])/(float)(255.0*1800*1.2);

        r = cvRound( - j * tabSin[n] + i * tabCos[n] );
        r = (numrho - 1) / 2 - r ;
        dst.at<float>(Point((r+1),(n+1))) += (float)(image[i*step+j])/(float)(255.0*1800*1.2);
      }
    }

  //find extremum
  float maxd = 0.00;
  int maxr=0, maxn = 0;

  float maxrhoex =0;
  int maxnex = 0;

  for(int n =0; n<numangle; n++) {
    int rhoex = 0;
    for(int r = 0; r<numrho; r++) {
      float d = dst.at<float>(Point(r+1,n+1));
      if ( (d>dst.at<float>(Point(r+2,n+1))) && (d>dst.at<float>(Point(r,n+1))) ) {
        rhoex++;
      }
    }
    if (rhoex > maxrhoex) {
      maxrhoex = rhoex;
      maxnex = n;
    }
  }
  printf("maxd=%0.3f, maxr=%d, maxn=%d | maxnex=%0.1f maxrhoex=%0.4f\n", maxd, maxr, maxn, (float)maxnex*90.0/(float)numangle, maxrhoex);
}
Example #16
0
void  DeNoiser::DeNoiseSemiStatic(Mat &image, AlgParameters* params) 
{
	if(params==NULL)
	{
		params = new AlgParameters();
		params->P0 = 1;
		params->P1 = 3;
		params->P2 = 1;
		params->P3 = 0;
		params->P4 = 10;
		params->P5 = 0;
		params->P6 = 0;
		params->P7 = 0;
		params->P8 = 0;
		params->P9 = 0;	
	}
	long t = getTickCount();
	if(params->P0>0)
	{		
		for(int i = 0;i<params->P1;i++)	medianBlur(image,image,params->P2*2+1);
	}
	if(params->P3 >0)
	{
		if(image_count<hist_size-1)
		{ 
			image.copyTo(*images[(hist_size-1)-image_count]);		
			image_count++;
		}
		else
		{
			//guardar el actual en el inicio del historial
			image.copyTo(*images[0]);	
			//poner el acumulador igual que la imagen
			image.convertTo(Accum,Accum.type());		
		
			int i,j,img,count;
			Mat* actual;
			uchar value;
			uchar base;
			float accum;
			for( i = 0; i < h; ++i)
			{
				for ( j = 0; j < w; ++j)
				{
					base = image.at<uchar>(i,j);
					accum = base;
					count = 1;
					for(img = 1; img<hist_size; ++img)
					{
						actual = images[img];
						value = actual->at<uchar>(i,j);
						if(abs(value-base)>params->P4) break;
						count++;
						accum+=value;
					}
					Accum.at<float>(i,j) = accum/count;
				}
			}

			//poner el resultado en la imagen
			Accum.convertTo(image,image.type());
		
			//correr las imagenes
			Mat* last = images[hist_size-1];
			for(int i =hist_size-1;i>0;i--) images[i] = images[i-1];
			images[0] = last;
		}
	}

	t = getTickCount() - t;
	float time = t*1000/getTickFrequency();
	if(first_time)
	{
		printf("Noise time: %fms, Fps: %f\n",time,1000/time);
		first_time = false;
	}
}
Example #17
0
  void PlateLines::processImage(Mat inputImage, vector<TextLine> textLines, float sensitivity)
  {
    if (this->debug)
      cout << "PlateLines findLines" << endl;

    timespec startTime;
    getTimeMonotonic(&startTime);


    // Ignore input images that are pure white or pure black
    Scalar avgPixelIntensity = mean(inputImage);
    if (avgPixelIntensity[0] >= 252)
      return;
    else if (avgPixelIntensity[0] <= 3)
      return;

    // Do a bilateral filter to clean the noise but keep edges sharp
    Mat smoothed(inputImage.size(), inputImage.type());
    adaptiveBilateralFilter(inputImage, smoothed, Size(3,3), 45, 45);


    int morph_elem  = 2;
    int morph_size = 2;
    Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );


    Mat edges(inputImage.size(), inputImage.type());
    Canny(smoothed, edges, 66, 133);

    // Create a mask that is dilated based on the detected characters


    Mat mask = Mat::zeros(inputImage.size(), CV_8U);

    for (unsigned int i = 0; i < textLines.size(); i++)
    {
      vector<vector<Point> > polygons;
      polygons.push_back(textLines[i].textArea);
      fillPoly(mask, polygons, Scalar(255,255,255));
    }



    dilate(mask, mask, getStructuringElement( 1, Size( 1 + 1, 2*1+1 ), Point( 1, 1 ) ));
    bitwise_not(mask, mask);

    // AND canny edges with the character mask
    bitwise_and(edges, mask, edges);


    vector<PlateLine> hlines = this->getLines(edges, sensitivity, false);
    vector<PlateLine> vlines = this->getLines(edges, sensitivity, true);
    for (unsigned int i = 0; i < hlines.size(); i++)
      this->horizontalLines.push_back(hlines[i]);
    for (unsigned int i = 0; i < vlines.size(); i++)
      this->verticalLines.push_back(vlines[i]);

    // if debug is enabled, draw the image
    if (this->debug)
    {
      Mat debugImgHoriz(edges.size(), edges.type());
      Mat debugImgVert(edges.size(), edges.type());
      edges.copyTo(debugImgHoriz);
      edges.copyTo(debugImgVert);
      cvtColor(debugImgHoriz,debugImgHoriz,CV_GRAY2BGR);
      cvtColor(debugImgVert,debugImgVert,CV_GRAY2BGR);

      for( size_t i = 0; i < this->horizontalLines.size(); i++ )
      {
        line( debugImgHoriz, this->horizontalLines[i].line.p1, this->horizontalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA);
      }

      for( size_t i = 0; i < this->verticalLines.size(); i++ )
      {
        line( debugImgVert, this->verticalLines[i].line.p1, this->verticalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA);
      }

      vector<Mat> images;
      images.push_back(debugImgHoriz);
      images.push_back(debugImgVert);

      Mat dashboard = drawImageDashboard(images, debugImgVert.type(), 1);
      displayImage(pipelineData->config, "Hough Lines", dashboard);
    }

    if (pipelineData->config->debugTiming)
    {
      timespec endTime;
      getTimeMonotonic(&endTime);
      cout << "Plate Lines Time: " << diffclock(startTime, endTime) << "ms." << endl;
    }

  }
Example #18
0
//Prints basic info about image
void imgInfo(const Mat& img){
	std::cout << "Type: " << img.type()
					<<"  Channels: " << img.channels()
					<< "   Depth:" << img.depth()
					<< std::endl;
}
Mat PicOpt::Optimize9Patch::ResizeImageRect(const Mat &img,
	const cv::Rect &rc,
	bool is_hrz,
	Vec2i &new_patch)
{
	if (rc.area() <= 0)
	{
		return img;
	}

	auto size = img.size();
	if (is_hrz)
	{
		cv::Rect left(Point(), size);
		cv::Rect center = left;
		cv::Rect right = left;

		int width = (std::min)(rc.width, center_width_);
		left.width = rc.x;
		center.x = rc.x + (rc.width - width) / 2;
		center.width = width;
		right.x = rc.x + rc.width;            // note that the line is [x, y) 
		right.width = size.width - right.x;

		Mat out(size.height, left.width + center.width + right.width, img.type());
		cv::Rect out_center = center;
		out_center.x = left.width;
		cv::Rect out_right = right;
		out_right.x = left.width + center.width;
		CopyImageRect(img, left, out, left);
		CopyImageRect(img, center, out, out_center);
		CopyImageRect(img, right, out, out_right);
		new_patch[0] = left.width;
		new_patch[1] = right.width;
		return out;
	}
	else
	{
		cv::Rect top(Point(), size);
		cv::Rect center = top;
		cv::Rect bottom = top;

		int height = (std::min)(rc.height, center_width_);
		top.height = rc.y;
		center.y = rc.y + (rc.height - height) / 2;
		center.height = height;
		bottom.y = rc.y + rc.height;
		bottom.height = size.height - bottom.y;

		Mat out(top.height + center.height + bottom.height, size.width, img.type());
		cv::Rect out_center = center;
		out_center.y = top.height;
		cv::Rect out_bottom = bottom;
		out_bottom.y = top.height + center.height;
		CopyImageRect(img, top, out, top);
		CopyImageRect(img, center, out, out_center);
		CopyImageRect(img, bottom, out, out_bottom);
		new_patch[0] = top.height;
		new_patch[1] = bottom.height;
		return out;
	}
}
Example #20
0
static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat())
{
    _dst.create(_src.size(), _src.type());
    int i, j, k, n = _dst.cols + _dst.rows - 1;
    Mat wave = _wave;
    double scale = (flags & DFT_SCALE) ? 1./n : 1.;
    size_t esz = _src.elemSize();
    size_t srcstep = esz, dststep = esz;
    const uchar* src0 = _src.ptr();
    uchar* dst0 = _dst.ptr();

    CV_Assert( _src.cols + _src.rows - 1 == n );

    if( wave.empty() )
        wave = initDFTWave( n, (flags & DFT_INVERSE) != 0 );

    const Complexd* w = wave.ptr<Complexd>();
    if( !_src.isContinuous() )
        srcstep = _src.step;
    if( !_dst.isContinuous() )
        dststep = _dst.step;

    if( _src.type() == CV_32FC2 )
    {
        for( i = 0; i < n; i++ )
        {
            Complexf* dst = (Complexf*)(dst0 + i*dststep);
            Complexd sum(0,0);
            int delta = i;
            k = 0;

            for( j = 0; j < n; j++ )
            {
                const Complexf* src = (const Complexf*)(src0 + j*srcstep);
                sum.re += src->re*w[k].re - src->im*w[k].im;
                sum.im += src->re*w[k].im + src->im*w[k].re;
                k += delta;
                k -= (k >= n ? n : 0);
            }

            dst->re = (float)(sum.re*scale);
            dst->im = (float)(sum.im*scale);
        }
    }
    else if( _src.type() == CV_64FC2 )
    {
        for( i = 0; i < n; i++ )
        {
            Complexd* dst = (Complexd*)(dst0 + i*dststep);
            Complexd sum(0,0);
            int delta = i;
            k = 0;

            for( j = 0; j < n; j++ )
            {
                const Complexd* src = (const Complexd*)(src0 + j*srcstep);
                sum.re += src->re*w[k].re - src->im*w[k].im;
                sum.im += src->re*w[k].im + src->im*w[k].re;
                k += delta;
                k -= (k >= n ? n : 0);
            }

            dst->re = sum.re*scale;
            dst->im = sum.im*scale;
        }
    }
    else
        CV_Error(CV_StsUnsupportedFormat, "");
}
void czh_thin_LUT(Mat & srcImage, Mat & dstImage, int iterations)
{
	// 该函数输入一个二值图像或者灰度图像,输出该图像的骨骼
	if (srcImage.type() != CV_8UC1)
	{
		cerr << "只能处理二值或灰度图像.\n";
		cerr << "读取图像函数: imread() 加上参数 \"0\" 或许可以修复该问题.\n";
		return;
	}

	// 用于查表法的表
	int array[256] = {	0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
						1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
						0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
						1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
						1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
						0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,
						0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
						1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
						0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
						1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
						1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
						1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
						1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,
						1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0 };

	// 准备临时 Mat 对象
	Mat tempImage;
	srcImage.copyTo(dstImage);
	srcImage.copyTo(tempImage);

	// 为了保证效果,先做膨胀操作,使断点连接起来
	dilate(srcImage, dstImage, getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)), Point(-1, -1), 3);
	
	// 该算法是用于黑色像素,所以先翻转图像进行抽取骨架操作,最后再转换回去
	MatIterator_<uchar> itBegin, itEnd;
	for (itBegin = dstImage.begin<uchar>(), itEnd = dstImage.end<uchar>(); itBegin != itEnd; itBegin++)
	{
		(*itBegin) = abs((*itBegin) - 255);
	}

	// 开始迭代
	int pointValue;

	uchar * ptrTop, *ptrCur, *ptrBot; // 8邻域中上一行,当前行和下一行的行指针
	uchar * dstPtr;	// 目标图像当前行指针

	// 因为是 8 邻域操作,所以宽和高各减1,防止指针溢出
	const int height = srcImage.rows - 1;
	const int width = srcImage.cols - 1;

	for (int loop = 0; loop < iterations; loop++)
	{
		bool changed = false;	// 判断该次迭代是否修改了像素颜色

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//																														   //
		//													遍历扫描过程一:开始                                                    //
		//																														   //
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		bool next = true;			// 重置跳跃监视符
		dstImage.copyTo(tempImage);	// 每次迭代,都将修改过后的目标图像复制给临时图像进行检查处理

		for (int i = 1; i < height; i++)
		{
			// 给3*3邻域中每一行行指针赋值
			ptrTop = tempImage.ptr<uchar>(i - 1);
			ptrCur = tempImage.ptr<uchar>(i);
			ptrBot = tempImage.ptr<uchar>(i + 1);
			dstPtr = dstImage.ptr<uchar>(i);

			for (int j = 1; j < width; j++)
			{
				if (((int)ptrCur[j - 1] + (int)ptrCur[j] + (int)ptrCur[j + 1]) == 0)	// 如果该点左右邻居都是黑色,则跳过该点不做处理
				{
					dstPtr[j] = ptrCur[j];
					continue;
				};

				if (next == false)	// 如果修改完某个点( next 会被置为 false),则跳过下一个点不做处理
				{
					next = true;
					dstPtr[j] = ptrCur[j];
					continue;
				};

				if ((int)ptrCur[j] == 0)	// 如果某个点为黑色,进行判断
				{
					pointValue = 0;

					// 第一行
					if ((int)(ptrTop[j - 1]) == 255)
					{
						pointValue += 1;
					}
					if ((int)(ptrTop[j]) == 255)
					{
						pointValue += 2;
					}
					if ((int)(ptrTop[j + 1]) == 255)
					{
						pointValue += 4;
					}

					// 第二行
					if ((int)(ptrCur[j - 1]) == 255)
					{
						pointValue += 8;
					}
					if ((int)(ptrCur[j]) == 255)
					{
						pointValue += 0;
					}
					if ((int)(ptrCur[j + 1]) == 255)
					{
						pointValue += 16;
					}

					// 第三行
					if ((int)(ptrBot[j - 1]) == 255)
					{
						pointValue += 32;
					}
					if ((int)(ptrBot[j]) == 255)
					{
						pointValue += 64;
					}
					if ((int)(ptrBot[j + 1]) == 255)
					{
						pointValue += 128;
					}

					dstPtr[j] = 255 * array[pointValue];

					if (dstPtr[j] == 255)	
					{
						next = false;	// 如果修改了当前像素(从黑变为白),则跳过下一个点
						changed = true;	// 并且把 changed 设置为true
					}
					else dstPtr[j] = ptrCur[j];
				}
			}
		}

		// 将最上下两行,左右两列变为白色
		ptrTop = dstImage.ptr<uchar>(0);
		ptrBot = dstImage.ptr<uchar>(dstImage.rows - 1);

		for (int i = 0; i < dstImage.cols; i++)
		{
			ptrTop[i] = 255;
			ptrBot[i] = 255;
		}
		for (int i = 0; i < dstImage.rows; i++)
		{
			dstImage.at<uchar>(i, 0) = 255;
			dstImage.at<uchar>(i, dstImage.cols - 1) = 255;
		}

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//																														   //
		//													遍历扫描过程二:开始                                                    //
		//																														   //
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		next = true;			// 重置跳跃监视符
		dstImage.copyTo(tempImage);	// 每次迭代,都将修改过后的目标图像复制给临时图像进行检查处理

		for (int j = 1; j < width; j++)
		{
			for (int i = 1; i < height; i++)
			{
				// 给3*3邻域中每一行行指针赋值
				ptrTop = tempImage.ptr<uchar>(i - 1);
				ptrCur = tempImage.ptr<uchar>(i);
				ptrBot = tempImage.ptr<uchar>(i + 1);
				dstPtr = dstImage.ptr<uchar>(i);

				if (((int)ptrTop[j] + (int)ptrCur[j] + (int)ptrBot[j]) == 0)	// 如果该点上下邻居都是黑色,则跳过该点不做处理
				{
					dstPtr[j] = ptrCur[j];
					continue;
				};

				if (next == false)	// 如果修改完某个点( next 会被置为 false),则跳过下一个点不做处理
				{
					next = true;
					dstPtr[j] = ptrCur[j];
					continue;
				};

				if ((int)ptrCur[j] == 0)	// 如果某个点为黑色,进行判断
				{
					pointValue = 0;

					// 第一行
					if ((int)(ptrTop[j - 1]) == 255)
					{
						pointValue += 1;
					}
					if ((int)(ptrTop[j]) == 255)
					{
						pointValue += 2;
					}
					if ((int)(ptrTop[j + 1]) == 255)
					{
						pointValue += 4;
					}

					// 第二行
					if ((int)(ptrCur[j - 1]) == 255)
					{
						pointValue += 8;
					}
					if ((int)(ptrCur[j]) == 255)
					{
						pointValue += 0;
					}
					if ((int)(ptrCur[j + 1]) == 255)
					{
						pointValue += 16;
					}

					// 第三行
					if ((int)(ptrBot[j - 1]) == 255)
					{
						pointValue += 32;
					}
					if ((int)(ptrBot[j]) == 255)
					{
						pointValue += 64;
					}
					if ((int)(ptrBot[j + 1]) == 255)
					{
						pointValue += 128;
					}

					dstPtr[j] = 255 * array[pointValue];

					if (dstPtr[j] == 255)	// 如果修改了当前像素(从黑变为白),则跳过下一个点
					{
						next = false;	// 如果修改了当前像素(从黑变为白),则跳过下一个点
						changed = true;	// 并且把 changed 设置为true
					}
					else dstPtr[j] = ptrCur[j];
				}
			}
		}

		// 将最上下两行,左右两列变为白色
		ptrTop = dstImage.ptr<uchar>(0);
		ptrBot = dstImage.ptr<uchar>(dstImage.rows - 1);
		for (int i = 0; i < dstImage.cols; i++)
		{
			ptrTop[i] = 255;
			ptrBot[i] = 255;
		}
		for (int i = 0; i < dstImage.rows; i++)
		{
			dstImage.at<uchar>(i, 0) = 255;
			dstImage.at<uchar>(i, dstImage.cols - 1) = 255;
		}

		if (changed == false)
		{
			break;	// 如果一次迭代没有删除任何像素,则认为已经结束细化,则直接退出
		}
	}

	// 最后再反转黑白
	for (itBegin = dstImage.begin<uchar>(), itEnd = dstImage.end<uchar>(); itBegin != itEnd; itBegin++)
	{
		(*itBegin) = abs((*itBegin) - 255);
	}
}
Example #22
0
static void mulComplex( const Mat& src1, const Mat& src2, Mat& dst, int flags )
{
    dst.create(src1.rows, src1.cols, src1.type());
    int i, j, depth = src1.depth(), cols = src1.cols*2;

    CV_Assert( src1.size == src2.size && src1.type() == src2.type() &&
              (src1.type() == CV_32FC2 || src1.type() == CV_64FC2) );

    for( i = 0; i < dst.rows; i++ )
    {
        if( depth == CV_32F )
        {
            const float* a = src1.ptr<float>(i);
            const float* b = src2.ptr<float>(i);
            float* c = dst.ptr<float>(i);

            if( !(flags & CV_DXT_MUL_CONJ) )
                for( j = 0; j < cols; j += 2 )
                {
                    double re = (double)a[j]*(double)b[j] - (double)a[j+1]*(double)b[j+1];
                    double im = (double)a[j+1]*(double)b[j] + (double)a[j]*(double)b[j+1];

                    c[j] = (float)re;
                    c[j+1] = (float)im;
                }
            else
                for( j = 0; j < cols; j += 2 )
                {
                    double re = (double)a[j]*(double)b[j] + (double)a[j+1]*(double)b[j+1];
                    double im = (double)a[j+1]*(double)b[j] - (double)a[j]*(double)b[j+1];

                    c[j] = (float)re;
                    c[j+1] = (float)im;
                }
        }
        else
        {
            const double* a = src1.ptr<double>(i);
            const double* b = src2.ptr<double>(i);
            double* c = dst.ptr<double>(i);

            if( !(flags & CV_DXT_MUL_CONJ) )
                for( j = 0; j < cols; j += 2 )
                {
                    double re = a[j]*b[j] - a[j+1]*b[j+1];
                    double im = a[j+1]*b[j] + a[j]*b[j+1];

                    c[j] = re;
                    c[j+1] = im;
                }
            else
                for( j = 0; j < cols; j += 2 )
                {
                    double re = a[j]*b[j] + a[j+1]*b[j+1];
                    double im = a[j+1]*b[j] - a[j]*b[j+1];

                    c[j] = re;
                    c[j+1] = im;
                }
        }
    }
}
Example #23
0
void WeightingDeblurer::deblur(int idx, Mat &frame)
{
    CV_INSTRUMENT_REGION()

    CV_Assert(frame.type() == CV_8UC3);

    bSum_.create(frame.size());
    gSum_.create(frame.size());
    rSum_.create(frame.size());
    wSum_.create(frame.size());

    for (int y = 0; y < frame.rows; ++y)
    {
        for (int x = 0; x < frame.cols; ++x)
        {
            Point3_<uchar> p = frame.at<Point3_<uchar> >(y,x);
            bSum_(y,x) = p.x;
            gSum_(y,x) = p.y;
            rSum_(y,x) = p.z;
            wSum_(y,x) = 1.f;
        }
    }

    for (int k = idx - radius_; k <= idx + radius_; ++k)
    {
        const Mat &neighbor = at(k, *frames_);
        float bRatio = at(idx, *blurrinessRates_) / at(k, *blurrinessRates_);
        Mat_<float> M = getMotion(idx, k, *motions_);

        if (bRatio > 1.f)
        {
            for (int y = 0; y < frame.rows; ++y)
            {
                for (int x = 0; x < frame.cols; ++x)
                {
                    int x1 = cvRound(M(0,0)*x + M(0,1)*y + M(0,2));
                    int y1 = cvRound(M(1,0)*x + M(1,1)*y + M(1,2));

                    if (x1 >= 0 && x1 < neighbor.cols && y1 >= 0 && y1 < neighbor.rows)
                    {
                        const Point3_<uchar> &p = frame.at<Point3_<uchar> >(y,x);
                        const Point3_<uchar> &p1 = neighbor.at<Point3_<uchar> >(y1,x1);
                        float w = bRatio * sensitivity_ /
                                (sensitivity_ + std::abs(intensity(p1) - intensity(p)));
                        bSum_(y,x) += w * p1.x;
                        gSum_(y,x) += w * p1.y;
                        rSum_(y,x) += w * p1.z;
                        wSum_(y,x) += w;
                    }
                }
            }
        }
    }

    for (int y = 0; y < frame.rows; ++y)
    {
        for (int x = 0; x < frame.cols; ++x)
        {
            float wSumInv = 1.f / wSum_(y,x);
            frame.at<Point3_<uchar> >(y,x) = Point3_<uchar>(
                    static_cast<uchar>(bSum_(y,x)*wSumInv),
                    static_cast<uchar>(gSum_(y,x)*wSumInv),
                    static_cast<uchar>(rSum_(y,x)*wSumInv));
        }
    }
}
void open_stream(int width, int height, Ptr<BackgroundSubtractor> pMOG) {
	Mat thr;
	Mat dst;

	while (true) {
		if (!g_cam->capture() == NULL) {
			if (g_cam->capture() == NULL) {
				std::cout << "Error: stream is empty" << std::endl;
			}
			else {
				// save the data stream in each frame
				IplImage* frame = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 1);
				frame -> imageData = (char*) g_cam-> capture();

///////////////////////
				// SET VIEW OF INTEREST
				cvSetImageROI(frame, cvRect(250, 200, 930, 600));
				frameMat = Mat(frame);
///////////////////////

				frameMat = Mat(frame);

				// show stream
				cvShowImage("Stream", frame);
   
		        if (char(key) == 27) { // ESC breaks the loop
		            break;      
		        }
		        else if (char(key) == 32) { // Space saves the current image
		        	//cvSaveImage("current.png", frame);
		        	cvSaveImage("min.png", frame);
		        	minI = imread("min.png", CV_LOAD_IMAGE_GRAYSCALE);
		        	//maskI = imread("mask4.bmp", CV_LOAD_IMAGE_GRAYSCALE);
		        	//bitwise_not(maskI, maskI);

		        }
		        else if (char(key) == 10) { // Enter takes an image of the background
		        	//cvSaveImage("background.png", frame);
		        	maxI = imread("background.png", CV_LOAD_IMAGE_GRAYSCALE);
		        	//threshold(maxI, maskI, 25, 255, CV_THRESH_BINARY); //65
		        	//pMOG->operator()(background, MaskMOG);
		        	
		        }
		        else if(char(key) ==  49 ) {
		        	++_delta;
		        }
		        else if(char(key) ==  33 ) {
		        	--_delta;
		        }
		        else if(char(key) ==  50 ) {
		        	_min_area += 100;
		        }
		        else if(char(key) ==  34 ) {
		        	_min_area -= 100;
		        }
		        else if(char(key) ==  51 ) {
		        	_max_area += 100;
		        }
		        else if(char(key) ==  35 ) {
		        	_max_area -= 100;
		        }
		        else if(char(key) ==  52 ) {
		        	_max_variation += 0.2;
		        }
		        else if(char(key) ==  36 ) {
		        	_max_variation -= 0.2;
		        }
		        else if(char(key) ==  53 ) {
		        	_max_variation += 0.1;
		        }
		        else if(char(key) ==  37 ) {
		        	_max_variation -= 0.1;
		        }
		        else if(char(key) ==  54 ) {
		        	g_cam->setGain(1.05 * g_cam->getGain());
		        }
		        else if(char(key) ==  38 ) {
		        	g_cam->setGain(0.95 * g_cam->getGain());
		        }
		        else if (char(key) == 43) {
		        	max_intens = Mat(frame);
		        }
		        
		        Mat black(frameMat.rows, frameMat.cols, frameMat.type(), Scalar::all(0));
		        //black.copyTo(frameMat, maskI);

		        if(maxI.data && minI.data) {
		        	subtract(Mat(frame), minI, temp2, noArray(), -1);
			    	subtract(maxI, minI, temp3, noArray(), -1);
			    	frameMat = ( temp2 / temp3) * pow(2, 8);
			    }
			    else {
			    	frameMat = Mat(frame);
			    }

			    if (ALGORITHM == 0) {
			    	get_contours(frameMat);
			    }
				else if (ALGORITHM == 1) {
					mser_algo(frameMat);
				}
				else if (ALGORITHM == 2) {
					get_contours(frameMat);
					mser_algo(frameMat);
				}
				else {
					std::cout << "Error: invalide algorithm number" << std::endl;
				}

		        key = cvWaitKey(10); // throws a segmentation fault (?)
	    	}
		}		
	}
}
Example #25
0
void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, Mat &norm, int nbins) const
{
    CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 );
    int x, y, binIdx;

    Size gradSize(img.size());
    Size histSize(histogram[0].size());
    Mat grad(gradSize, CV_32F);
    Mat qangle(gradSize, CV_8U);

    AutoBuffer<int> mapbuf(gradSize.width + gradSize.height + 4);
    int* xmap = (int*)mapbuf + 1;
    int* ymap = xmap + gradSize.width + 2;

    const int borderType = (int)BORDER_REPLICATE;

    for( x = -1; x < gradSize.width + 1; x++ )
        xmap[x] = borderInterpolate(x, gradSize.width, borderType);
    for( y = -1; y < gradSize.height + 1; y++ )
        ymap[y] = borderInterpolate(y, gradSize.height, borderType);

    int width = gradSize.width;
    AutoBuffer<float> _dbuf(width*4);
    float* dbuf = _dbuf;
    Mat Dx(1, width, CV_32F, dbuf);
    Mat Dy(1, width, CV_32F, dbuf + width);
    Mat Mag(1, width, CV_32F, dbuf + width*2);
    Mat Angle(1, width, CV_32F, dbuf + width*3);

    float angleScale = (float)(nbins/CV_PI);

    for( y = 0; y < gradSize.height; y++ )
    {
        const uchar* currPtr = img.data + img.step*ymap[y];
        const uchar* prevPtr = img.data + img.step*ymap[y-1];
        const uchar* nextPtr = img.data + img.step*ymap[y+1];
        float* gradPtr = (float*)grad.ptr(y);
        uchar* qanglePtr = (uchar*)qangle.ptr(y);

        for( x = 0; x < width; x++ )
        {
            dbuf[x] = (float)(currPtr[xmap[x+1]] - currPtr[xmap[x-1]]);
            dbuf[width + x] = (float)(nextPtr[xmap[x]] - prevPtr[xmap[x]]);
        }
        cartToPolar( Dx, Dy, Mag, Angle, false );
        for( x = 0; x < width; x++ )
        {
            float mag = dbuf[x+width*2];
            float angle = dbuf[x+width*3];
            angle = angle*angleScale - 0.5f;
            int bidx = cvFloor(angle);
            angle -= bidx;
            if( bidx < 0 )
                bidx += nbins;
            else if( bidx >= nbins )
                bidx -= nbins;

            qanglePtr[x] = (uchar)bidx;
            gradPtr[x] = mag;
        }
    }
    integral(grad, norm, grad.depth());

    float* histBuf;
    const float* magBuf;
    const uchar* binsBuf;

    int binsStep = (int)( qangle.step / sizeof(uchar) );
    int histStep = (int)( histogram[0].step / sizeof(float) );
    int magStep = (int)( grad.step / sizeof(float) );
    for( binIdx = 0; binIdx < nbins; binIdx++ )
    {
        histBuf = (float*)histogram[binIdx].data;
        magBuf = (const float*)grad.data;
        binsBuf = (const uchar*)qangle.data;

        memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
        histBuf += histStep + 1;
        for( y = 0; y < qangle.rows; y++ )
        {
            histBuf[-1] = 0.f;
            float strSum = 0.f;
            for( x = 0; x < qangle.cols; x++ )
            {
                if( binsBuf[x] == binIdx )
                    strSum += magBuf[x];
                histBuf[x] = histBuf[-histStep + x] + strSum;
            }
            histBuf += histStep;
            binsBuf += binsStep;
            magBuf += magStep;
        }
    }
}
Example #26
0
    void BTVL1_Base::process(InputArrayOfArrays _src, OutputArray _dst, InputArrayOfArrays _forwardMotions,
                             InputArrayOfArrays _backwardMotions, int baseIdx)
    {
        CV_Assert( scale_ > 1 );
        CV_Assert( iterations_ > 0 );
        CV_Assert( tau_ > 0.0 );
        CV_Assert( alpha_ > 0.0 );
        CV_Assert( btvKernelSize_ > 0 );
        CV_Assert( blurKernelSize_ > 0 );
        CV_Assert( blurSigma_ >= 0.0 );

        CV_OCL_RUN(_src.isUMatVector() && _dst.isUMat() && _forwardMotions.isUMatVector() &&
                   _backwardMotions.isUMatVector(),
                   ocl_process(_src, _dst, _forwardMotions, _backwardMotions, baseIdx))

        std::vector<Mat> & src = *(std::vector<Mat> *)_src.getObj(),
                & forwardMotions = *(std::vector<Mat> *)_forwardMotions.getObj(),
                & backwardMotions = *(std::vector<Mat> *)_backwardMotions.getObj();

        // update blur filter and btv weights
        if (!filter_ || blurKernelSize_ != curBlurKernelSize_ || blurSigma_ != curBlurSigma_ || src[0].type() != curSrcType_)
        {
            filter_ = createGaussianFilter(src[0].type(), Size(blurKernelSize_, blurKernelSize_), blurSigma_);
            curBlurKernelSize_ = blurKernelSize_;
            curBlurSigma_ = blurSigma_;
            curSrcType_ = src[0].type();
        }

        if (btvWeights_.empty() || btvKernelSize_ != curBtvKernelSize_ || alpha_ != curAlpha_)
        {
            calcBtvWeights(btvKernelSize_, alpha_, btvWeights_);
            curBtvKernelSize_ = btvKernelSize_;
            curAlpha_ = alpha_;
        }

        // calc high res motions
        calcRelativeMotions(forwardMotions, backwardMotions, lowResForwardMotions_, lowResBackwardMotions_, baseIdx, src[0].size());

        upscaleMotions(lowResForwardMotions_, highResForwardMotions_, scale_);
        upscaleMotions(lowResBackwardMotions_, highResBackwardMotions_, scale_);

        forwardMaps_.resize(highResForwardMotions_.size());
        backwardMaps_.resize(highResForwardMotions_.size());
        for (size_t i = 0; i < highResForwardMotions_.size(); ++i)
            buildMotionMaps(highResForwardMotions_[i], highResBackwardMotions_[i], forwardMaps_[i], backwardMaps_[i]);

        // initial estimation
        const Size lowResSize = src[0].size();
        const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_);

        resize(src[baseIdx], highRes_, highResSize, 0, 0, INTER_CUBIC);

        // iterations
        diffTerm_.create(highResSize, highRes_.type());
        a_.create(highResSize, highRes_.type());
        b_.create(highResSize, highRes_.type());
        c_.create(lowResSize, highRes_.type());

        for (int i = 0; i < iterations_; ++i)
        {
            diffTerm_.setTo(Scalar::all(0));

            for (size_t k = 0; k < src.size(); ++k)
            {
                // a = M * Ih
                remap(highRes_, a_, backwardMaps_[k], noArray(), INTER_NEAREST);
                // b = HM * Ih
                filter_->apply(a_, b_);
                // c = DHM * Ih
                resize(b_, c_, lowResSize, 0, 0, INTER_NEAREST);

                diffSign(src[k], c_, c_);

                // a = Dt * diff
                upscale(c_, a_, scale_);
                // b = HtDt * diff
                filter_->apply(a_, b_);
                // a = MtHtDt * diff
                remap(b_, a_, forwardMaps_[k], noArray(), INTER_NEAREST);

                add(diffTerm_, a_, diffTerm_);
            }

            if (lambda_ > 0)
            {
                calcBtvRegularization(highRes_, regTerm_, btvKernelSize_, btvWeights_, ubtvWeights_);
                addWeighted(diffTerm_, 1.0, regTerm_, -lambda_, 0.0, diffTerm_);
            }

            addWeighted(highRes_, 1.0, diffTerm_, tau_, 0.0, highRes_);
        }

        Rect inner(btvKernelSize_, btvKernelSize_, highRes_.cols - 2 * btvKernelSize_, highRes_.rows - 2 * btvKernelSize_);
        highRes_(inner).copyTo(_dst);
    }
Example #27
0
void GetRValue()
{
    cout << "R start.."<<endl;
    int locatr,locatc;
    Mat l1 = Mat(grayImg.rows,grayImg.cols,grayImg.type()), l2 = Mat(grayImg.rows,grayImg.cols,grayImg.type());
    double lambda1,lambda2,d,a,b,c,min = 10000000000,max = -10000000000;
    rImg = Mat(grayImg.rows,grayImg.cols,CV_64F);
    Mat Img = Mat(grayImg.rows,grayImg.cols,CV_8U);
    Mat featurePointImg = Mat(grayImg.rows,grayImg.cols,CV_8U);
    Mat temperatureImg = Mat(grayImg.rows,grayImg.cols,CV_8UC3);
    double** r = (double**)malloc(grayImg.rows*sizeof(double*));
    uchar** image = (uchar**)malloc(grayImg.rows*sizeof(uchar*));
    uchar** feature = (uchar**)malloc(grayImg.rows*sizeof(uchar*));
    uchar** temperature = (uchar**)malloc(grayImg.rows*sizeof(uchar*));
    for(int i=0;i<grayImg.rows;i++)
    {
        r[i] = rImg.row(i).ptr<double>();
        image[i] = Img.row(i).ptr<uchar>();
        feature[i] = featurePointImg.row(i).ptr<uchar>();
        temperature[i] = temperatureImg.row(i).ptr<uchar>();
    }
    for(int i=0;i<grayImg.rows-length;i++)
        for (int j=0;j<grayImg.cols-length; j++) {
            locatr = i+length/2;
            locatc = j+length/2;
            a = 0;
            b = 0;
            c = 0;
            for(int rr=0; rr<length;rr++)
                for(int cc=0; cc<length ;cc++)
                {
                    a += xpd[i+rr][j+cc]*xpd[i+rr][j+cc];
                    b += xpd[i+rr][j+cc]*ypd[i+rr][j+cc];
                    c += ypd[i+rr][j+cc]*ypd[i+rr][j+cc];
                }
            lambda1 = ((a+c)+sqrt(4*b*b+(a-c)*(a-c)))/2;
            lambda2 = ((a+c)-sqrt(4*b*b+(a-c)*(a-c)))/2;
            d = lambda1*lambda2-k*(lambda1+lambda2)*(lambda1+lambda2);
            r[locatr][locatc] = d;
            if(min > d) min = d;
            if(max < d) max = d;
            if(d>Threshold)
                image[locatr][locatc] = 255;
            else
               image[locatr][locatc] = 0;
        }
    int rr,cc,x,y;
    for(int i=0;i<featurePointImg.rows;i++)
        for(int j=0;j<featurePointImg.cols;j++)
        {
            if( r[i][j] < Threshold )
            {
                feature[i][j] = 0;
                continue;
            }
            feature[i][j] = 255;
            for(x = -5;x<5;x++)
            {
                rr = i+x;
                if(rr<0||rr>=rImg.rows) continue;
                for (y = -5; y<5; y++) {
                    cc = j+y;
                    if(cc<0||cc>=rImg.cols) continue;
                    if(x == 0 && y == 0) continue;
                    if (r[rr][cc] >= r[i][j]) {
                        feature[i][j] = 0;
                        break;
                    }
                }
                if ( feature[i][j] == 0) break;
            }
            if(feature[i][j] == 255)
                circle(inputImg, Point(j,i), 1, CV_RGB(255, 0, 0),2);
        }
    
    double gap = max - min;
    int base = (1<<24)-1;
    for(int i=0;i<temperatureImg.rows;i++)
        for(int j=0;j<temperatureImg.cols;j++)
        {
            d = (r[i][j]-min)/gap*base;
            temperature[i][j*3] = uchar(int(d)%(256));
            temperature[i][j*3+1] = uchar(int(d)%(1<<16)/256);
            temperature[i][j*3+2] = uchar(int(d)/(1<<16));
        }
    
    imshow("img", temperatureImg);
    imwrite(temperatureName, temperatureImg);
    waitKey();
    
    imshow("img", Img);
    imwrite(rName, Img);
    waitKey();
    
    imshow("img", featurePointImg);
    imwrite(featureName, featurePointImg);
    cout << "R finished.." << endl;
    waitKey();
}
Example #28
0
void HoughDiscreteV_( const Mat &img, int max_dx, int dbx, int ddx, Mat &dst) {
  int i,j;
  cv::AutoBuffer<short> _accum;
  
  CV_Assert( img.type() == CV_8UC1 );
  
  const uchar *image = img.ptr();
  int step = (int)img.step;
  int width = img.cols;
  int height = img.rows;
  
  printf("HD: width:%d height:%d\n",width,height);
  
  int num_bx = width/dbx + 1;
  int num_dx = (2*max_dx + 1)/ddx;
  
  if (dst.empty()) {
    printf("dst_create: num_bx:%d, num_dx:%d\n", num_bx, num_dx);
    dst.create( num_dx, num_bx, CV_32F );
  }    

  _accum.allocate((num_bx+2) * (num_dx+2));
  short *accum = _accum;
  memset( accum, 0, sizeof(accum[0]) * (num_bx+2) * (num_dx+2) );
  
  dst = Scalar::all(0);
  for(int y=0;y<height;y++) {
    for(int x=0;x<width;x++) {
      if (image[y*step+x] == 0) continue;

      //Bresenham? oh no?
/*
      int mdx = round((float)max_dx*y/height);
      
      int min_basex = max(0, x - mdx);
      min_basex = dbx*floor(min_basex/dbx);
      int max_basex = min(width-1, x + mdx);

//      printf("(x,y)=(%d,%d) => basex = [%d, %d]\n", x,y, min_basex, max_basex);       
*/
      float y_h = (float)y / (float)height;

      for(int _dx=0; _dx<num_dx; _dx+=1) {
        int basex = x + round((float)_dx * ddx * y_h);

        if (basex < 0) continue;
        if (basex >= width) continue;
 
        int bx = basex/dbx;

        accum[ (_dx+1)*(num_bx+2) + bx+1]++;       
//        dst.at<float>( (max_dx + dx) / ddx, basex / dbx)++;
      }           
    }
  }

/*
  for(int basex=0; basex<width; basex+=dbx ) {
//    printf("basex: %d [%d,%d]\n",basex, max(0,basex-max_dx), min(basex+max_dx, width));
    for(int x=max(0, basex-max_dx); x<=min(basex+max_dx,width-1); x+=ddx) {

      float r = (float)BresenhamLineIntegrate(basex, 0, x, height-1, img);
      
      dst.at<uchar>( (max_dx + (x - basex))/ddx, basex/dbx) = r/(float)height/2.0; 
    }
  }
*/
}
Example #29
0
// S1
int HistologicalEntities::plFindNucleusCandidates(const Mat& img, Mat& seg_norbc,
		::cciutils::SimpleCSVLogger *logger, ::cciutils::cv::IntermediateResultHandler *iresHandler) {
	std::vector<Mat> bgr;
	split(img, bgr);
	if (logger) logger->logTimeSinceLastLog("toRGB");

	Mat background = ::nscale::HistologicalEntities::getBackground(bgr, logger, iresHandler);

	int bgArea = countNonZero(background);
	float ratio = (float)bgArea / (float)(img.size().area());
//TODO: TMEP	std::cout << " background size: " << bgArea << " ratio: " << ratio << std::endl;
	if (logger) logger->log("backgroundRatio", ratio);

	if (ratio >= 0.99) {
		//TODO: TEMP std::cout << "background.  next." << std::endl;
		if (logger) logger->logTimeSinceLastLog("background");
		return ::nscale::HistologicalEntities::BACKGROUND;
	} else if (ratio >= 0.9) {
		//TODO: TEMP std::cout << "background.  next." << std::endl;
		if (logger) logger->logTimeSinceLastLog("background likely");
		return ::nscale::HistologicalEntities::BACKGROUND_LIKELY;
	}

	if (logger) logger->logTimeSinceLastLog("background");
	if (iresHandler) iresHandler->saveIntermediate(background, 1);

	Mat rbc = ::nscale::HistologicalEntities::getRBC(bgr, logger, iresHandler);
	if (logger) logger->logTimeSinceLastLog("RBC");
	int rbcPixelCount = countNonZero(rbc);
	if (logger) logger->log("RBCPixCount", rbcPixelCount);

//	imwrite("test/out-rbc.pbm", rbc);
	if (iresHandler) iresHandler->saveIntermediate(rbc, 2);

	/*
	rc = 255 - r;
    rc_open = imopen(rc, strel('disk',10));
    rc_recon = imreconstruct(rc_open,rc);
    diffIm = rc-rc_recon;
	 */

	Mat rc = ::nscale::PixelOperations::invert<unsigned char>(bgr[2]);
	if (logger) logger->logTimeSinceLastLog("invert");

	Mat rc_open(rc.size(), rc.type());
	//Mat disk19 = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
	// structuring element is not the same between matlab and opencv.  using the one from matlab explicitly....
	// (for 4, 6, and 8 connected, they are approximations).
	unsigned char disk19raw[361] = {
			0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
			0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
			0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
			0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
			0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
			0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
			0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0};
	std::vector<unsigned char> disk19vec(disk19raw, disk19raw+361);
	Mat disk19(disk19vec);
	disk19 = disk19.reshape(1, 19);
	rc_open = ::nscale::morphOpen<unsigned char>(rc, disk19);
//	morphologyEx(rc, rc_open, CV_MOP_OPEN, disk19, Point(-1, -1), 1);
	if (logger) logger->logTimeSinceLastLog("open19");
	if (iresHandler) iresHandler->saveIntermediate(rc_open, 3);

// for generating test data 
//	imwrite("test/in-imrecon-gray-marker.pgm", rc_open);
//	imwrite("test/in-imrecon-gray-mask.pgm", rc);
//	exit(0);
// END for generating test data
	Mat rc_recon = ::nscale::imreconstruct<unsigned char>(rc_open, rc, 8);
	if (iresHandler) iresHandler->saveIntermediate(rc_recon, 4);


	Mat diffIm = rc - rc_recon;
//	imwrite("test/out-redchannelvalleys.ppm", diffIm);
	if (logger) logger->logTimeSinceLastLog("reconToNuclei");
	int rc_openPixelCount = countNonZero(rc_open);
	if (logger) logger->log("rc_openPixCount", rc_openPixelCount);
	if (iresHandler) iresHandler->saveIntermediate(diffIm, 5);

/*
    G1=80; G2=45; % default settings
    %G1=80; G2=30;  % 2nd run

    bw1 = imfill(diffIm>G1,'holes');
 *
 */
	unsigned char G1 = 80;
	Mat diffIm2 = diffIm > G1;
	if (logger) logger->logTimeSinceLastLog("threshold1");
	if (iresHandler) iresHandler->saveIntermediate(diffIm2, 6);

//	imwrite("in-fillHolesDump.ppm", diffIm2);
	Mat bw1 = ::nscale::imfillHoles<unsigned char>(diffIm2, true, 4);
//	imwrite("test/out-rcvalleysfilledholes.ppm", bw1);
	if (logger) logger->logTimeSinceLastLog("fillHoles1");
	if (iresHandler) iresHandler->saveIntermediate(bw1, 7);

//	// TODO: change back
//	return ::nscale::HistologicalEntities::SUCCESS;
/*
 *     %CHANGE
    [L] = bwlabel(bw1, 8);
    stats = regionprops(L, 'Area');
    areas = [stats.Area];

    %CHANGE
    ind = find(areas>10 & areas<1000);
    bw1 = ismember(L,ind);
    bw2 = diffIm>G2;
    ind = find(bw1);

    if isempty(ind)
        return;
    end
 *
 */
	int compcount2;

//#if defined (USE_UF_CCL)
	Mat bw1_t = ::nscale::bwareaopen2(bw1, false, true, 11, 1000, 8, compcount2);
//	printf(" cpu compcount 11-1000 = %d\n", compcount2);
//#else
//	Mat bw1_t = ::nscale::bwareaopen<unsigned char>(bw1, 11, 1000, 8, compcount);
//#endif
	if (logger) logger->logTimeSinceLastLog("areaThreshold1");

	bw1.release();
	if (iresHandler) iresHandler->saveIntermediate(bw1_t, 8);
	if (compcount2 == 0) {
		return ::nscale::HistologicalEntities::NO_CANDIDATES_LEFT;
	}


	unsigned char G2 = 45;
	Mat bw2 = diffIm > G2;
	if (iresHandler) iresHandler->saveIntermediate(bw2, 9);


	/*
	 *
    [rows,cols] = ind2sub(size(diffIm),ind);
    seg_norbc = bwselect(bw2,cols,rows,8) & ~rbc;
    seg_nohole = imfill(seg_norbc,'holes');
    seg_open = imopen(seg_nohole,strel('disk',1));
	 *
	 */

	seg_norbc = ::nscale::bwselect<unsigned char>(bw2, bw1_t, 8);
	if (iresHandler) iresHandler->saveIntermediate(seg_norbc, 10);

	seg_norbc = seg_norbc & (rbc == 0);
	if (iresHandler) iresHandler->saveIntermediate(seg_norbc, 11);

//	imwrite("test/out-nucleicandidatesnorbc.ppm", seg_norbc);
	if (logger) logger->logTimeSinceLastLog("blobsGt45");


	return ::nscale::HistologicalEntities::CONTINUE;

}
Example #30
0
void myChaccum(cv::Mat & A,vector<int>& radiusRange,int method,int objPolarity,double edgeThresh,cv::Mat & accumMatrix,cv::Mat &  gradientImg){
	double maxNumElemNHoodMat = 1e6;

	//Mat accumMatrix_2d(accumMatrix.size(),CV_64FC2);

	Mat Gx,Gy;

	//A gradientImg 都是32float
	imgradient(A,Gx,Gy,gradientImg);
	
	//cout<<gradientImg<<endl;

	vector<int> Ey,Ex,idxE;

	getEdgeM_PIxels( gradientImg,edgeThresh,Ey,Ex);

	mysub2ind(gradientImg.size(),Ey,Ex,idxE);

	
	vector<float> radiusfRange;

	float radius_tmp = radiusRange[0];
	float steplength = 0.5;
	while(radius_tmp<=radiusRange[1]){
		radiusfRange.push_back(radius_tmp);
		radius_tmp += steplength;
	}
	vector<float> RR;
	switch(objPolarity){

	case bright:
		RR = radiusfRange;
		break;
	case dark:
		RR = radiusfRange ;
		for(int i=0;i<RR.size();i++){
			RR.at(i) *= -1.0;
		}
		break;
	default:
		break;
	}
	//
	//

	vector<float> lnR;
	vector<float> phi;
	Mat Opca(cv::Size(radiusfRange.size(),1),CV_32FC2);
	Mat w0(cv::Size(radiusfRange.size(),1),CV_32FC2);

	float phi_t= 0.0;
	float opca_R = 0.0;
	float opca_I= 0.0;
	float w0_R = 0.0;
	float w0_I = 0.0;

	int i = 0;

	switch(method){
	case twostage:
		
		for(i=0;i<radiusfRange.size();i++){
			w0.at<cv::Vec2f>(0,i)[0] = 1/(2*M_PI*radiusfRange.at(i));
			w0.at<cv::Vec2f>(0,i)[1]  =0.0;
		}
		break;
	case phasecode:

		for(i=0;i<radiusfRange.size();i++){
			float  w_t = log(radiusfRange.at(i));
			lnR.push_back(w_t);
		}
		
		for(int i=0;i<radiusfRange.size();i++){
			phi_t = ((lnR.at(i) - lnR.at(0)) / ( lnR.at(radiusfRange.size()-1) - lnR.at(0))*2*M_PI)-M_PI;
			phi.push_back(phi_t);
			opca_R = cos(phi_t);//exp(sqrt(-1)*phi_t);//虚数
			opca_I = sin(phi_t);

			Opca.at<cv::Vec2f>(0,i)[0] = opca_R;
			Opca.at<cv::Vec2f>(0,i)[1] = opca_I;

			w0_R  = opca_R / (2*M_PI*radiusfRange.at(i));
			w0_I  = opca_I / (2*M_PI*radiusfRange.at(i));
			
			w0.at<cv::Vec2f>(0,i)[0] = w0_R;
			w0.at<cv::Vec2f>(0,i)[1] = w0_I;

		}
		break;

	default:
			break;	
	}
	//cout<<"radiusfRange : "<<radiusfRange.size()<<endl;
	int xcStep = floor(maxNumElemNHoodMat/RR.size());
	//
	int lenE = Ex.size();

	accumMatrix.setTo(Scalar::all(0));
	//cout<<accumMatrix<<endl;
	vector<int> Ex_chunk;
	vector<int> Ey_chunk;
	vector<int> idxE_chunk;
	vector<bool> rows_to_keep;
	Mat xc;
	Mat yc;
	Mat w;
	Mat inside;
	
	Mat xc_new;
	Mat yc_new;
	Mat w_new;
	Mat inside_new;
	Mat m_yxc;
	Mat m_wval;
	vector<int> xc_vec,yc_vec;
	vector<float> w_vecR,w_vecI;
	for(int i =0;i<lenE;i += xcStep){
		
		Ex_chunk.clear();
		Ey_chunk.clear();
		idxE_chunk.clear();
		for(int j=i;j<min((i+xcStep-1),(lenE));j++){
			Ex_chunk.push_back(Ex.at(j)); 
			Ey_chunk.push_back(Ey.at(j)); 
			idxE_chunk.push_back(idxE.at(j));
		}//j
		
		xc.release();
		yc.release();
		w.release();
		inside.release();

		xc.create(cv::Size(RR.size(),Ex_chunk.size()),CV_32SC1);
		yc.create(cv::Size(RR.size(),Ex_chunk.size()),CV_32SC1);
		w.create(cv::Size(RR.size(),Ex_chunk.size()),CV_32FC2);
		inside.create(cv::Size(RR.size(),Ex_chunk.size()),CV_8UC1);


		int M = A.rows;
		int N = A.cols;
	

		for (int t=0;t<idxE_chunk.size();t++)
		{
			int x = idxE_chunk.at(t) / gradientImg.rows ;
			
			int y = idxE_chunk.at(t)%(gradientImg.rows );
			//cout<<t<<": "<<Ex_chunk.at(t)<<endl;
			for (int j=0;j<xc.cols;j++)
			{
	
					//============================---------------------------------------------------===========
					//============================================================
				double fxc = (-1)*RR.at(j) * Gx.at<float>(y,x)/gradientImg.at<float>(y,x) + Ex_chunk.at(t);
					int txc = /*min*/(RoundEx(fxc)/*,479*/);
					//cout<<gradientImg<<endl;
					xc.at<int>(t,j) = txc;
					
					int tyc = /*min*/(RoundEx((-1)*RR.at(j) * Gy.at<float>(y,x)/gradientImg.at<float>(y,x) + Ey_chunk.at(t))/*,639*/);
					
					yc.at<int>(t,j) = tyc;
					
					w.at<cv::Vec2f>(t,j)[0] = w0.at<cv::Vec2f>(0,j)[0];
					w.at<cv::Vec2f>(t,j)[1] = w0.at<cv::Vec2f>(0,j)[1];

					//Determine which edge M_PIxel votes are wirhin the image domain
					bool inside_t = (xc.at<int>(t,j) >= 0) && (xc.at<int>(t,j)<N) && (yc.at<int>(t,j) >= 0) && (yc.at<int>(t,j) < M);

					inside.at<uchar>(t,j) = inside_t?1:0;//
			}//j
			
		}//t
		//cout<<xc<<endl;

	//	//Keep rows that have at least one candidate position inside the domain
		int sum_ture = 0;
		rows_to_keep.clear();
		for(int t=0;t<inside.rows;t++){
			bool rows_to_keep_tmp = false;
			for (int j=0;j<inside.cols;j++){
				
				if(inside.at<uchar>(t,j)>0){
					rows_to_keep_tmp = true;
					sum_ture++;
					break;
				}
			}//j
			rows_to_keep.push_back(rows_to_keep_tmp);
		
		}//t
		xc_new.release();
		yc_new.release();
		w_new.release();
		inside_new.release();

		xc_new.create(cv::Size(xc.cols,sum_ture),CV_32SC1);
		yc_new.create(cv::Size(yc.cols,sum_ture),CV_32SC1);
		w_new.create(cv::Size(w.cols,sum_ture),w.type());
		inside_new.create(cv::Size(inside.cols,sum_ture),inside.type());

		for (int t=0,f=0;t<xc.rows;t++)
		{
			if(rows_to_keep.at(t)){
				for (int j=0;j<xc.cols;j++)
				{
					xc_new.at<int>(f,j) = xc.at<int>(t,j);
					yc_new.at<int>(f,j) = yc.at<int>(t,j);
					w_new.at<cv::Vec2f>(f,j)[0] = w.at<cv::Vec2f>(t,j)[0];
					w_new.at<cv::Vec2f>(f,j)[1] = w.at<cv::Vec2f>(t,j)[1];
					inside_new.at<uchar>(f,j) = inside.at<uchar>(t,j);

				}
				f++;
			}
			
		}//t

		//accumulate the votes in the parameter plane
		//1.向量化
		xc_vec.clear();
		yc_vec.clear();
		w_vecR.clear();
		w_vecI.clear();
		m_yxc.release();
		m_wval.release();
		for (int j=0;j<inside_new.cols;j++)
		{
			for (int t =0;t<inside_new.rows;t++)
			{
				if((inside_new.at<uchar>(t,j))==1){
					xc_vec.push_back(xc_new.at<int>(t,j));
					yc_vec.push_back(yc_new.at<int>(t,j));
					w_vecR.push_back(w_new.at<cv::Vec2f>(t,j)[0]);
					w_vecI.push_back(w_new.at<cv::Vec2f>(t,j)[1]);
				}
			}//t
			
		}//j
		
		m_yxc.create(cv::Size(2,xc_vec.size()),CV_32SC1);
		m_wval.create(cv::Size(1,xc_vec.size()),CV_32FC2);
		for(int j=0;j<yc_vec.size();j++){
			m_yxc.at<int>(j,0) = yc_vec.at(j);
			m_yxc.at<int>(j,1) = xc_vec.at(j);
			m_wval.at<cv::Vec2f>(j,0)[0] = w_vecR.at(j);
			m_wval.at<cv::Vec2f>(j,0)[1] = w_vecI.at(j);
			//cout<<w_vecR.at(j)<<","<<w_vecI.at(j)<<endl;
		}
		Mat_<cv::Vec2f> accumR;
		myaccumarray(m_yxc,m_wval,accumR,A.size());
		//cout<<"accumR"<<endl;
		accumMatrix += accumR;
		//cout<<accumMatrix<<endl;

	}
}