- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有这张图片和 3 个辣椒:
我需要将这张图片转换为 HSV 格式,然后将每个辣椒分成自己的图像。
到目前为止,我似乎能够很好地将红辣椒与其他辣椒区分开来。但是,我似乎无法弄清楚如何分离其他辣椒。
这是我的代码:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cmath>
#include <string>
#include <vector>
int main(int argc, char *argv[]){
cv::Mat im_in;
cv::Mat hsv_in;
cv::Mat bgr_in;
cv::Mat orig_in;
cv::Mat im_o1;
cv::Mat im_o2;
cv::Mat im_o3;
// Read image
if (argc<2){
im_in = cv::imread("colorpeppers.jpg");
}
if (argc==2){
im_in=cv::imread((argv[1]));
}
if (argc>2){
std::cout<<"Error! Too many arguments!"<<std::endl;
}
if (im_in.empty()){
std::cout << "error detected. something went wrong with opening the image. is it empty? exiting"<<std::endl;
return -1;
}
cv::Mat orig_image = im_in.clone();
cv::medianBlur(im_in, im_in, 3);
cv::cvtColor(im_in, hsv_in, cv::COLOR_BGR2HSV);
cv::namedWindow("Original Image", cv::WINDOW_AUTOSIZE);
cv::imshow("Orginal Image", im_in);
cv::namedWindow("Orginal Image converted to HSV", cv::WINDOW_AUTOSIZE);
cv::imshow("Original Image converted to HSV", hsv_in);
cv::Mat lower_red_hue_range;
cv::Mat upper_red_hue_range;
cv::Mat lower_green_hue_range;
cv::Mat upper_green_hue_range;
cv::Mat lower_yellow_hue_range;
cv::Mat upper_yellow_hue_range;
cv::inRange(hsv_in, cv::Scalar(0,100,100), cv::Scalar(10,255,255), lower_red_hue_range);
cv::inRange(hsv_in, cv::Scalar(160,100,100),cv::Scalar(179, 255, 255), upper_red_hue_range);
cv::inRange(hsv_in, cv::Scalar(0,100,100), cv::Scalar(10,255,255), lower_green_hue_range);
cv::inRange(hsv_in, cv::Scalar(50,100,100),cv::Scalar(70,255,255), upper_green_hue_range);
cv::inRange(hsv_in, cv::Scalar(0,100,100),cv::Scalar(20,0,0),lower_yellow_hue_range);
cv::inRange(hsv_in,cv::Scalar(10,100,100),cv::Scalar(50,110,110),upper_yellow_hue_range);
//combining the above
cv::Mat red_hue_image=im_in.clone();
cv::Mat green_hue_image=im_in.clone();
cv::Mat yellow_hue_image=im_in.clone();
cv::addWeighted(lower_red_hue_range, 1.0, upper_red_hue_range, 1.0, 0.0, red_hue_image);
cv::addWeighted(lower_green_hue_range, 1.0, upper_green_hue_range, 1.0, 0.0, green_hue_image);
cv::addWeighted(lower_yellow_hue_range, 1.0, upper_yellow_hue_range, 1.0, 0.0, yellow_hue_image);
cv::GaussianBlur(red_hue_image, red_hue_image, cv::Size(9,9), 2, 2);
cv::GaussianBlur(green_hue_image, green_hue_image, cv::Size(9,9),2,2);
cv::GaussianBlur(yellow_hue_image, yellow_hue_image, cv::Size(9,9),2,2);
cv::namedWindow("Threshold lower red image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold lower red image", lower_red_hue_range);
cv::namedWindow("Threshold upper red image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold upper red image", upper_red_hue_range);
cv::namedWindow("Combined Threshold red Images", cv::WINDOW_AUTOSIZE);
cv::imshow("Combined Threshold red Images", red_hue_image);
cv::namedWindow("Threshold lower green image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold lower green image", lower_green_hue_range);
cv::namedWindow("Threshold upper green image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold upper green image", upper_green_hue_range);
cv::namedWindow("Combined Threshold green Images", cv::WINDOW_AUTOSIZE);
cv::imshow("Combined Threshold green Images", green_hue_image);
cv::namedWindow("Threshold lower yellow image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold lower yellow image", lower_yellow_hue_range);
cv::namedWindow("Threshold upper yellow image", cv::WINDOW_AUTOSIZE);
cv::imshow("Threshold upper yellow image", upper_yellow_hue_range);
cv::namedWindow("Combined Threshold yellow Images", cv::WINDOW_AUTOSIZE);
cv::imshow("Combined Threshold yellow Images", yellow_hue_image);
//cv::Mat redpepper;//=red_hue_image.clone();
//cv::Mat redpepper_hsv;
//cvtColor(redpepper, redpepper_hsv,CV_BGR2HSV);
// for(int i = 0; i < redpepper.rows;i++){
// for(int j = 0; j <redpepper.cols;j++){
char k;
for (int x=1;x<15;x++){
k=cvWaitKey(0);
}
}
最佳答案
第一步,让我们使用 k-means clustering 减少图像中的颜色数量.
接下来,让我们将图像转换为 HSV 空间并将其拆分为单独的色调、饱和度和明度分量。
色调:
色调(彩色映射):
饱和度:
值:
色调分量足以用于算法的其余部分。我们通过在适合三种颜色的范围内选择像素来创建三个蒙版。
红色:
黄色:
绿色:
我们使用形态变换(侵 eclipse 、扩张)清理蒙版图像。接下来,我们检测轮廓并只选择面积大于某个阈值的轮廓(我选择了 5000 像素)。我们通过填充满足标准的轮廓来生成新的蒙版。
红色:
黄色:
绿色:
例如,现在我们可以绘制轮廓...
红色:
黄色:
绿色:
代码:
#include <opencv2/opencv.hpp>
#include <cstdint>
#include <iostream>
#include <vector>
cv::Mat cluster_image(cv::Mat const& img)
{
int K = 4;
int n = img.rows * img.cols;
cv::Mat data = img.reshape(1, n);
data.convertTo(data, CV_32F);
std::vector<int> labels;
cv::Mat1f colors;
cv::kmeans(data, K, labels
, cv::TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.0001)
, 5, cv::KMEANS_PP_CENTERS, colors);
for (int i = 0; i < n; ++i) {
data.at<float>(i, 0) = colors(labels[i], 0);
data.at<float>(i, 1) = colors(labels[i], 1);
data.at<float>(i, 2) = colors(labels[i], 2);
}
cv::Mat reduced = data.reshape(3, img.rows);
reduced.convertTo(reduced, CV_8U);
return reduced;
}
cv::Mat filter_mask(cv::Mat& img, cv::Mat& mask)
{
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
cv::Mat filtered;
cv::erode(mask, filtered, kernel, cv::Point(-1, -1), 2);
cv::dilate(filtered, filtered, kernel, cv::Point(-1, -1), 2);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(filtered, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::Mat output_mask = cv::Mat::zeros(mask.size(), CV_8UC1);
double const MIN_CONTOUR_AREA(5000.0);
for (int i(0); i < contours.size(); ++i) {
double area = cv::contourArea(contours[i]);
if (area >= MIN_CONTOUR_AREA) {
cv::drawContours(output_mask, contours, i, cv::Scalar(255), CV_FILLED);
}
}
cv::dilate(output_mask, output_mask, kernel, cv::Point(-1, -1), 1);
return output_mask;
}
void highlight_mask(std::string const& filename, cv::Mat& img, cv::Mat& mask)
{
cv::Mat output = img.clone();
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::drawContours(output, contours, 0, cv::Scalar(255, 0, 0), 2);
cv::imwrite(filename, output);
}
int main(int argc, char *argv[])
{
cv::Mat orig_image(cv::imread("d:\\code\\shit\\so03\\bin\\runtime\\Debug\\peppers.png"));
if (orig_image.empty()) {
std::cerr << "Input image empty." << std::endl;
return -1;
}
cv::Mat im_in;
cv::medianBlur(orig_image, im_in, 3);
cv::Mat clustered = cluster_image(im_in);
cv::imwrite("peppers_clustered.png", clustered);
cv::Mat hsv_in;
cv::cvtColor(clustered, hsv_in, cv::COLOR_BGR2HSV);
uint32_t HUE(0), SAT(1), VAL(2);
std::vector<cv::Mat> h_s_v(3);
cv::split(hsv_in, h_s_v);
cv::imwrite("peppers_hue.png", h_s_v[HUE]);
cv::imwrite("peppers_sat.png", h_s_v[SAT]);
cv::imwrite("peppers_val.png", h_s_v[VAL]);
cv::Mat red_mask_a;
cv::inRange(h_s_v[HUE], cv::Scalar(2), cv::Scalar(10), red_mask_a);
cv::Mat red_mask_b = filter_mask(im_in, red_mask_a);
cv::imwrite("peppers_red_mask_a.png", red_mask_a);
cv::imwrite("peppers_red_mask_b.png", red_mask_b);
cv::Mat yellow_mask_a;
cv::inRange(h_s_v[HUE], cv::Scalar(15), cv::Scalar(25), yellow_mask_a);
cv::Mat yellow_mask_b = filter_mask(im_in, yellow_mask_a);
cv::imwrite("peppers_yellow_mask_a.png", yellow_mask_a);
cv::imwrite("peppers_yellow_mask_b.png", yellow_mask_b);
cv::Mat green_mask_a;
cv::inRange(h_s_v[HUE], cv::Scalar(40), cv::Scalar(50), green_mask_a);
cv::Mat green_mask_b = filter_mask(im_in, green_mask_a);
cv::imwrite("peppers_green_mask_a.png", green_mask_a);
cv::imwrite("peppers_green_mask_b.png", green_mask_b);
highlight_mask("peppers_red_out.png", orig_image, red_mask_b);
highlight_mask("peppers_yellow_out.png", orig_image, yellow_mask_b);
highlight_mask("peppers_green_out.png", orig_image, green_mask_b);
}
关于c++ - 无法在 C++ OpenCV HSV 图像分离中分离对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36390083/
我必须使用 opencv 开发 android 代码,代码相当于 MATLAB。因为我必须读取图像并将其转换为 HSV,我已经使用: Imgproc.cvtColor(temp, hsv , Im
我正在寻找从 RGB 到 HSV 的颜色空间转换器,特别是用于两种颜色空间的 0 到 255 范围。 最佳答案 我已经使用了很长时间 - 现在不知道它们是从哪里来的......请注意,输入和输出,除了
我正在使用 openCV 3.1.0(我试过 2.4.9,但有同样的问题)。我想将 HSV 垫输出到 jpeg: // .. Getting JPEG content into memory // J
我有这段代码可以将 RGB 转换为 HSV func rgbToHSV (_ r:Double, _ g:Double, _ b:Double) -> (Double, Double, Doubl
我不熟悉图像检测技术。我正在使用 java openCV 来检测图像中的颜色。我能够检测到黄色和红色。我从命中和试用方法中获得了值(value),这些方法工作正常。但我还想从下面的手图像中检测绿色、橙
我正在开发一款应用程序, children 需要在其中使用相机屏幕上的特定目标点来找到特定的颜色 - 有点像增强现实。我已经完成了所有工作,但使用了 RGB 颜色。对于每种颜色,红色、绿色、蓝色、黄色
我有一个将 RGB 颜色空间中的 vector 转换为 HSV 的函数 - 该例程通过了所有测试并且在绝大多数时间都有效。然而,崩溃报告表明它偶尔会失败(0.0001% 的调用或更少)。但是,由于此函
我正在开发一个应用程序,该应用程序创建的图像的色调、饱和度和值会根据不同的参数发生变化。出于性能原因,最好分别渲染色调、饱和度和值组件,然后使用 Photoshop 风格的混合模式(乘法、叠加、屏幕、
我正在使用 matplotlib 中的 HSV 颜色图来绘制一些向量场。有没有办法使 HSV 颜色变暗或变得更平滑,使它们看起来更像这样 比我原来的绘图颜色太亮: 最佳答案 简介 假设您正在尝试绘制这
我正在尝试遍历 HSV 图像,但它一直在崩溃。 Mat a=imread("play.jpg"); Mat hsvimage, hsvimage2,cont; cvtColor(a,
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭10 年前。 Improve th
我听说,如果您需要在软件上进行颜色分割(如果满足某些阈值规则,例如 R100、10<,则通过将像素设置为 1,从彩色图像创建二进制图像) B < 123) 最好先将图像转换为 HSV。这是真的吗?为什
我正在 win32 api 中创建一个应用程序,它将使用进度条。这个进度条应该改变它的颜色。从红色(左端)到绿色(右端),中间有一些黄色。 我搜索了一下,发现我应该使用 HSV 来实现这一点。我就是不
虽然我通常更喜欢 RGB 颜色空间而不是 HSV,但我希望 SKEmitterNode 发射具有最大饱和度和值的粒子,并且具有涵盖所有颜色的色调值。这可能吗? 我是 XCode、Swift 和 Spr
假设我有两种 RGB 颜色 (255,0,0) 和 (0,0,255),我还需要它们之间的 100 种颜色。我如何根据许多所需步骤生成 HSV 颜色值列表? 当前使用 python 3 我创建了以下代
我正在从如下图像创建一个 hsv 直方图。 - (void)processImageWithHsv:(Mat&)image; { Mat image_hsv; cvtColor(ima
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我正在寻找一种为 3 channel 矩阵的元素赋值的有效方法。特别是,我需要将 HSV 值分配给 2D cv::Mat 的元素,其初始化如下: cv::Mat clusterImage(height
我正在尝试使用 openCV 和 C++ 来均衡 HSV 图像的直方图。我知道有些带有 openCV 的库可以为我执行此操作,但我想手动尝试以了解该方法。 我假设均衡将在 HSV 图像的 V chan
所以我一直在尝试使用 HSV 在一定程度范围内循环颜色,但我似乎无法在颜色之间平滑过渡。理想情况下,我希望能够在特定的度数范围 (80-140) 内移动,并在 0.5 - 1 之间循环饱和度和值。老实
我是一名优秀的程序员,十分优秀!