Related
in the following rectangle function, rectangles are drawn.
// Draw the predicted bounding box
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame)
{
//Draw a rectangle displaying the bounding box
rectangle(frame, Point(left, top), Point(right, bottom), Scalar(255, 178, 50),LINE_4);
//bluring region
cout << frame;
//Get the label for the class name and its confidence
string label = format("%.2f", conf);
if (!classes.empty())
{
CV_Assert(classId < (int)classes.size());
label = classes[classId] + ":" + label;
}
//Display the label at the top of the bounding box
int baseLine;
Size labelSize = getTextSize(label, FONT_ITALIC, 0.5, 1, &baseLine);
top = max(top, labelSize.height);
putText(frame, label, Point(left, top), FONT_ITALIC, 0.5, Scalar(255, 255, 255), 1);
}
frame here is a multi-array of the image.
Point(left, top) is the top-left point of the rectangle.
I would like to censor everything in this rectangle in the form of a blur.
Since I come from Python programming, it is a bit difficult to define the array of these rectangles.
It would be very nice if you could help me.
Thank you very much and best regards.
Here is the Python equivalent to #HansHirse's answer. The idea is the same except we use Numpy slicing to obtain the ROI
import cv2
# Read in image
image = cv2.imread('1.png')
# Create ROI coordinates
topLeft = (60, 40)
bottomRight = (340, 120)
x, y = topLeft[0], topLeft[1]
w, h = bottomRight[0] - topLeft[0], bottomRight[1] - topLeft[1]
# Grab ROI with Numpy slicing and blur
ROI = image[y:y+h, x:x+w]
blur = cv2.GaussianBlur(ROI, (51,51), 0)
# Insert ROI back into image
image[y:y+h, x:x+w] = blur
cv2.imshow('blur', blur)
cv2.imshow('image', image)
cv2.waitKey()
The way to go is setting up a corresponding region of interest (ROI) by using cv::Rect. Since you already have your top left and bottom right locations as cv::Points, you get this more or less for free. Afterwards, just use - for example - cv::GaussianBlur only on that ROI. Using the C++ API, this approach works for a lot of OpenCV methods.
The code is quite simple, see the following snippet:
// (Just use your frame instead.)
cv::Mat image = cv::imread("path/to/your/image.png");
// Top left and bottom right cv::Points are already defined.
cv::Point topLeft = cv::Point(60, 40);
cv::Point bottomRight = cv::Point(340, 120);
// Set up proper region of interest (ROI) using a cv::Rect from the two cv::Points.
cv::Rect roi = cv::Rect(topLeft, bottomRight);
// Only blur image within ROI.
cv::GaussianBlur(image(roi), image(roi), cv::Size(51, 51), 0);
For some exemplary input like this
the above code generates the following output:
Hope that helps!
I am trying to display an Image inside a QLabel on QT forms. I need that label to have only the top left and right corners to be rounded while the bottom 2 remain rectangular.
using style sheets I gave the border-radius a value and it worked. Howerver, the image inside that label remained rectangular. (the corner of the image hid the circular corner of the QLabel).
Searching around, i found that setting a mask to the image (pixmap) and drawing a RoundRect on it cause the corners to be circular.
that worked but it made all four corners of the image to be circular.
is there a way to make only the top part as circular?
this is how i made the edges of the pixmap circular:
QBitmap map(100,100); //my pixmap is 100x100
map.fill(Qt::color0);
QPainter painter( &map );
painter.setBrush(Qt::color1);
painter.drawRoundRect(0,0,100,100,20,20);
p.setMask(map);
ui->image1->setPixmap(p);
and this is how i made the QLabel top left and right corner circular
QString style = "border: 4px solid; \n";
style += "border-top-left-radius: 20px;\n";
style += "border-top-right-radius: 20px;";
ui->image1->setStyleSheet(style);
Your idea with the mask is not too bad. You just have to do some composite drawing to the mask, e.g.
QPainter painter(&map);
painter.setBrush(Qt::color1);
painter.drawRoundedRect(0, 0, 100, 40, 20, 20);
painter.drawRect(0, 20, 100, 100);
p.setMask(map);
I have a project to create a face detection program. One of the requirements is for me to draw a line across the center of the face.
Now the way I have done this is by first drawing a line across the two eyes (by getting each eye's coordinates and using them as line points) and then drawing a perpendicular line to that. This way I can account for face rotation aswell.
However this line is the same length as the line across the eyes. I want this perpendicular line to cut across the entire face if possible. Attached is an example of my output for one the rotated face images. I need the green line to be longer.
unfortunately your image is a jpeg so it has compression artifacts.
I first tried to extract the line, but that didnt give good angle information, so I use cv::minAreaRect after green area segmentation.
cv::Mat green;
cv::inRange(input, cv::Scalar(0,100,0), cv::Scalar(100,255,100),green);
// instead of this, maybe try to find contours and choose the right one, if there are more green "objects" in the image
std::vector<cv::Point2i> locations;
cv::findNonZero(green, locations);
// find the used color to draw in same color later
cv::Vec3d averageColorTmp(0,0,0);
for(unsigned int i=0; i<locations.size(); ++i)
{
averageColorTmp += input.at<cv::Vec3b>(locations[i]);
}
averageColorTmp *= 1.0/locations.size();
// compute direction of the segmented region
cv::RotatedRect line = cv::minAreaRect(locations);
// extract directions:
cv::Point2f start = line.center;
cv::Point2f rect_points[4];
line.points(rect_points);
cv::Point2f direction1 = rect_points[0] - rect_points[1];
cv::Point2f direction2 = rect_points[0] - rect_points[3];
// use dominant direction
cv::Point2f lineWidthDirection;
lineWidthDirection = (cv::norm(direction1) < cv::norm(direction2)) ? direction1 : direction2;
double lineWidth = cv::norm(lineWidthDirection);
cv::Point2f lineLengthDirection;
lineLengthDirection = (cv::norm(direction1) > cv::norm(direction2)) ? direction1 : direction2;
lineLengthDirection = 0.5*lineLengthDirection; // because we operate from center;
// input parameter:
// how much do you like to increase the line size?
// value of 1.0 is original size
// value of > 1 is increase of line
double scaleFactor = 3.0;
// draw the line
cv::line(input, start- scaleFactor*lineLengthDirection, start+ scaleFactor*lineLengthDirection, cv::Scalar(averageColorTmp[0],averageColorTmp[1],averageColorTmp[2]), lineWidth);
giving this result:
This method should be quite robust, IF there is no other green in the image but only the green line. If there are other green parts in the image you should extract contours first and choose the right contour to assign the variable locations
Ill write it out in pseudocode
Take the furthest right hand edge coordinate (row1,col1) in your image
Take the right hand point of your line (row2,col2)
Draw a line from that your line (row2,col2) to (row2,col1)
Repeat for the left hand side
This will result in drawing two additional lines from either side of your line to the edge of your image.
I want to identify and extract the contour of the largest leaf of the following image using OpenCV and C++.
I applied Canny edge detector to the image and got the following result.
Canny(img_src, img_edge_detected, 20, 60, 3);
Now I want to extract the largest contour (largest leaf) form the image and draw the contour line, but the problem here is the edge line of the largest leaf is not continuous. So I looked in to dialate and morphological close but using those functions I couldn't get a good result to extract the area. Is there any way to get the largest contour in such image?
Note that here I cannot use template matching or any masking kind of things because my final intention is to built a system where a user can upload an image and get the species of the plant. So the system doesn't have any prior idea about the shape of the leaf that user is going to upload.
Please tell me how to find and draw the largest contour here if it is possible.
Thanks.
cant you use hsv color threshoding to track only that leaf and then you can straight away use minmaxloc function to get the area of the largest contour.just an idea try doing it like that.it will work.good luck
Same thing i will do in java please convert it into c++, here BGR to convert HSV then after apply the combination of the yellow, green and brown with specified range and simply perfom bitwise or operation. it will be give to you not zero pixles using opencv function Core.findNonZero(Mat src, Mat dst);
Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_BGR2HSV, 4);
//Yellow
Core.inRange(mHSV, new Scalar(25, 80, 80), new Scalar(36, 255, 255), yellow);
//Green
Core.inRange(mHSV, new Scalar(37, 80, 80), new Scalar(70, 255, 255), green);
//Brown
Core.inRange(mHSV, new Scalar(10, 80, 80), new Scalar(30, 200, 200), brown);
// logical OR mask
Core.bitwise_or(yellow, green, green);
Core.bitwise_or(green, brown, mask);
Imgproc.dilate(mask, mask, new Mat());
// Find non zero pixels
pts = Mat.zeros(mask.size(), mask.type());
Core.findNonZero(mask, pts);
return mask;
Is it possible to achieve the following shadow effect in CSS?
It needs to go below an image/div.
The closest I have got so far is using
-webkit-box-shadow: 0px 20px 15px -10px #999;
-moz-box-shadow: 0px 20px 15px -10px #999;
box-shadow: 0px 20px 15px -10px #999;
This might not be a shadow per se, but I just generated this as a background via Ultimate CSS Gradient Generator
background: -moz-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(0,0,0,0.65) 48%, rgba(0,0,0,0) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(0,0,0,0)), color-stop(48%,rgba(0,0,0,0.65)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 48%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 48%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 48%,rgba(0,0,0,0) 100%); /* IE10+ */
background: linear-gradient(to right, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 48%,rgba(0,0,0,0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#00000000',GradientType=1 ); /* IE6-9 */
Multiple Box shadows are possible on one element, all you have to do is separate each box shadow with a comma. For example:
box-shadow: 5px 5px 5px grey, -5px 5px 5px blue, 5px -5px 5px orange;
This box shadow will produce 3 shadows, one in the top right with a color of grey, one in the bottom left with a color of blue, and one in the bottom right with a color of orange.
Here is the jsfiddle with the demo.
You can play around with the settings but to achieve those curves are quite hard and it might be easier with an image.
Use this code box-shadow: 0 45px 50px -50px #000000;